Qual é a maneira adequada de lidar com View e ViewModel no WPF?
Atualmente, estou fazendo um Editor com padrão MVVM em WPF. O Editor simplesmente pega uma instância de um tipo específico como referência e o modifica. O código a seguir é o uso esperado quando o desenvolvimento do editor for concluído.
MyEditor myEditor = new MyEditor();
myEditor.Show();
myEditor.Edit(myDataInstance1); // Bind myDataInstance1 to the editor and edit it.
myEditor.Edit(myDataInstance2);
myEditor.Clear();
myEditor.Close();
... and so on ...
Portanto, primeiro dividi o programa em Model, ViewModel e View. Mas, uma questão surgiu aqui. Onde devo declarar os métodos Show (), Edit (), Clear (), Close ()? E como cada classe View e ViewModel deve ser tratada? Eu pensei sobre isso assim, mas não encontrei uma boa alternativa.
- No construtor View, defina ViewModel como DataContext, crie uma instância de View, acesse o DataContext de View e chame o método ViewModel ...
- Acesse diretamente os métodos ViewModel. (View e ViewModel devem ser gerenciados separadamente)
- Crie uma classe independente chamada MyEditor para gerenciar View e ViewModel e conectar os métodos de ViewModel e MyEditor. Os usuários usam o método do MyEditor.
Dos métodos que pensei, o terceiro método é o mais provável, mas não tenho certeza. A composição do editor não é muito simples. Basicamente, o Editor é amplamente composto por View, ViewModel e Model, mas dentro do ViewModel, devo também lidar com sub views para vários MyChildTypes que podem ser editados. (Existem várias classes MyChildType que herdam a classe MyBaseType, e cada MyChildType tem sua própria visualização editável.) Portanto, se eu passar uma instância de MyChildType ao Editor, o Editor deverá mostrar uma visualização editável adequada para aquele tipo. A verificação de tipo e a substituição da subvisualização em si são fáceis, mas não conheço uma maneira adequada de definir a instância MyChildType para o editor. Aconselhe-me por favor.
Respostas
Geralmente, a abordagem MMVM requer que a exibição seja criada estaticamente por meio de XAML.
Quando você tem visualizações que existem dinamicamente, altere seu código para que, em vez disso, elas sempre existam e sejam visíveis dinamicamente.
Então, no seu caso, você teria algo como
<MainWindow>
<MyEditor ViewModel={Binding EditorViewModel}/>
</MainWindow>
e em seu controle ...
<MyEditor>
<Panel Visible={Binding IsVisible}>
.... actual stuff...
</Panel>
</MyEditor>
onde EditorViewModel.IsVisibleé inicialmente falso (e tem ligação apropriada)
Você pode então ter EditorViewModel.Load (data) .Clear () .Show () .Hide () etc etc
Dê uma olhada no caliburn micro
É uma estrutura baseada em convenção, portanto, se você tiver um modelo de visualização, ele mostrará automaticamente a visualização desse modelo. Portanto, você pode alterar a visualização apenas alterando a instância do modelo de visualização.
Você pode dar uma olhada no meu software de código aberto aqui que faz isso
https://github.com/AndersMalmgren/FreePIE
Se você não usar uma ferramenta baseada em convenção como o caliburn, você pode olhar para o padrão de comando WPF IC
edit: aqui está um exemplo, temos uma propriedade ViewModel de classe base
https://github.com/AndersMalmgren/FreePIE/blob/4e51cae1816e3eee915a9629503cb7c188579550/FreePIE.GUI/Views/Plugin/PluginPropertyViewModel.cs#L35
public ValueViewModel Value { get; set; }
Em vista, ser vinculado a isso por convenção
https://github.com/AndersMalmgren/FreePIE/blob/4e51cae1816e3eee915a9629503cb7c188579550/FreePIE.GUI/Views/Plugin/PluginPropertyView.xaml#L11
<ContentControl x:Name="Value"></ContentControl>
Qualquer modelo de visualização que você referenciar, a visualização correta será exibida.