Criando uma estratégia de diálogo amigável do MVVM

Estou tentando criar uma estratégia para lidar com formulários popup para uso em qualquer parte do meu aplicativo. Até agora, eu vou precisar de um único UserControl na raiz da minha MainWindow. Isso será vinculado ao seu próprio ViewModel, que manipulará as mensagens enviadas dentro do aplicativo.

Estou usando o MVVM Light e sou relativamente novo na class Messenger .

Imagine um cenário de mestre / detalhes, onde uma lista de objects está contida em um ListBox . Selecionar um desses itens e clicar em um botão Editar exibiria um UserControl que cobre a canvas inteira. O usuário pode editar o item selecionado e clicar em OK para confirmar a alteração.

Eu quero que o UserControl que é aberto para ser “genérico” de uma maneira que eu possa jogar qualquer (provavelmente um ViewModel) nele … para ele renderizar o ViewModel através de um DataTemplate e lidar com todas as mudanças de object. Clicar em OK retornará a chamada para a class de envio e persistirá a alteração como antes.

Algumas situações em que isso seria útil são …

  1. Exibir mensagens de erro sem a necessidade de input do usuário (diferente de OK para fechá-las)
  2. Exibir um formulário de edição para um item de dados
  3. Diálogos de confirmação (muito parecido com um MessageBox padrão)

Alguém pode fornecer amostras de código de como eu poderia conseguir isso?

Ao projetar uma UI com o MVVM, o objective é separar as preocupações da View das preocupações do ViewModel. Idealmente, o ViewModel não deve confiar em nenhum componente de visualização. No entanto, esse é o idal e outra regra do MVVM é que você deve projetar seu aplicativo como desejar.

Na área que fornece um serviço mostrando diálogos, existem duas abordagens diferentes:

  1. Implementando o DialogService na Visualização (por exemplo, consulte http://geekswithblogs.net/lbugnion/archive/2011/04/13/deep-dive-mvvm-samples-mix11-deepdivemvvm.aspx Exemplo 03).
  2. A implementação de um componente de serviço que não está anexado à exibição (por exemplo, consulte http://blog.roboblob.com/2010/01/19/modal-dialogs-with-mvvm-and-silverlight-4/ )

Ambas as abordagens dependem de uma interface que define a funcionalidade que o serviço fornece. A implementação deste Serviço é então injetada no ViewModel.

Além disso, ambas as abordagens têm suas vantagens e desvantagens específicas.

  • A primeira abordagem também funciona bem para o WP7, no entanto, requer uma class base de visão comum, pois ela contém a implementação do serviço de visualização.
  • A segunda abordagem funciona bem para o SilverLight e o WPF e aplica-se, pois mantém o serviço separado da exibição e não impõe nenhuma restrição à exibição.

Outra solução possível é usar o sistema de mensagens para mostrar os diálogos.

Qualquer que seja a abordagem que você esteja usando, tente manter o View e o ViewModel desacoplados usando um padrão IoC (inversão de controle), ou seja, defina uma interface para que você possa usar diferentes implementações. Para vincular os serviços ao ViewModel, use a injeção, isto é, passando o serviço para o construtor do ViewModel ou definindo uma propriedade.

Recentemente eu comecei a aprender MVVM para um aplicativo WPF que eu estava criando, eu usei este artigo como base para mostrar diálogos, se você baixar o projeto de amostra, então é realmente um bom método desacoplado, é bem abstraído e para obter uma visão você passar uma instância de um viewmodel. Eu estendi um pouco para os meus próprios meios, eu também usei o MessageBox WPFExtendedToolkit para avisos, erros etc porque o MessageBox win32 padrão é fugly.

No que diz respeito a formulários dynamics, então você vai querer investigar o ItemsControl, e no seu ViewModels ter uma coleção de itens de dados que precisam ser editados pelo usuário para o ItemsControl para vincular a. Eu tenho um diálogo para editar ações e seus parâmetros em um designer de sistema de stream de trabalho, onde a lista de diálogo de ações era totalmente dinâmica. Isso foi feito expondo uma coleção de meus itens com seus tipos de dados para que eu pudesse usar um DataTemplateSelector para selecionar DataTemplates que continha os tipos corretos de controles, ou seja, um tipo de dados de DateTime mostrava um DatePicker.

Espero que ajude

Do ponto de vista de um desenvolvedor chegando para ‘manter’ esse código genérico, parece uma dor. Do que você descreveu, eu daria ao formulário e ao diálogo o mesmo modelo de visualização e criaria um modelo XAML específico para a checkbox de diálogo que você deseja mostrar.