Qual é a maneira adequada de lidar com View e ViewModel no WPF?

Sep 08 2020

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

Ewan Sep 08 2020 at 20:51

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

Anders Sep 08 2020 at 20:42

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.