No meu aplicativo WPF, quero criar uma nova exibição. Onde devo fazer isso - no ViewModel ou Model ?
O aplicativo é (muito simples por enquanto) uma ferramenta semelhante a formulários de uma janela com um único botão "enviar". Caso uma das caixas de seleção esteja selecionada, uma nova janela usando o mesmo ViewModel deve aparecer para solicitar ao usuário alguns detalhes adicionais. Para os fins desta pergunta, vamos considerar apenas a nova abordagem de janela sem considerar outras abordagens, como o painel mostrado / oculto.
Idealmente, no View não deveria haver nenhum código. Além disso, como o View não possui lógica, a VM inicialmente precisaria verificar se é necessária a criação de um novo modo de exibição e - quando estiver - devolvendo essa responsabilidade ao View, levando ao inchaço do código.
Por outro lado, a criação de uma nova visualização no ViewModel viola o princípio de que o ViewModel não deve saber nada sobre o ViewModel.
Então, é melhor criar novas visualizações no View ou no ViewModel?
Respostas:
Eu uso injeção de dependência e um
IViewFactory
injetado no modelo de exibição para respeitar ambas as restrições.A
ProductViewModel
(por exemplo) chamathis.viewFactory.Show("Details", this)
para abrirProductDetailsView
consigo mesmo comoProductViewModel
. Também poderia abrir uma vista com base em outro modelo de vista comthis.viewFactory.Show<ClientViewModel>()
.A implementação (na verdade existem várias para WinForms, Windows Wpf simples, um shell Wpf com guias, ...) é baseada em uma
StructureMap
convenção. As visualizações designam seu modelo de visualização por meio de umaIView<ProductViewModel>
interface.Portanto, o modelo de exibição não sabe nada sobre a exibição, exceto sua função (exibição padrão, exibição de detalhes, ...) e a exibição não contém código para criar outra exibição. Além disso, os modelos de exibição estão em um assembly separado que não faz referência a nenhum assembly Wpf.
fonte
Resposta teórica
Se você tem a
ViewModel
, ações que têm efeitos estéticos (por exemplo, realçar um item ao passar o mouse) são o trabalho de umView
, enquanto ações que têm efeitos "reais" (por exemplo, gerando uma nova janela) são o trabalho deViewModel
.Como tal, criar uma nova janela é um trabalho para o
ViewModel
. No entanto, nem o View nem oViewModel
devem saber exatamente como criar uma janela, isso não faz parte de suas responsabilidades e pertence a uma classe diferente.Você poderia argumentar que criar uma nova janela é um trabalho para o
View
. Embora eu discorde, há pouco valor nesse debate, porque, na prática, não é o fim do mundo se você colocar esse código no arquivoView
, e também não há muito trabalho em movê-lo paraViewModel
um ponto posterior. . A parte importante é que a lógica para a criação de uma nova janela está contida em uma classe independente, geralmente algum tipo de WindowFactory. O objetivo do MVVM, MVP, MVC, etc é que você tem classes com poucas e bem definidas responsabilidades. É por isso que você não adicionar responsabilidades adicionais para oView
,ViewModel
ouModel
se você não precisa.Sob nenhuma circunstância a criação da Janela pertence ao
Model
, porque eleModel
nem está ciente de que existe algo como uma GUI.Resposta prática
Trata-se de uma "ferramenta semelhante ao formulário de uma janela com um único botão" enviar "" . Então, aqui está um plug descarado para uma resposta minha: Por que usar o MVVM?
Para resumir o que essa resposta diz: Seja simples. Ah, e lembre-se de implementar a resposta teórica acima quando a janela de um único botão começar a se tornar mais complexa.
fonte