A maioria dos exemplos de MVVM em que trabalhei tiveram o modelo implementado INotifyPropertyChanged
, mas no exemplo CommandSink de Josh Smith, o ViewModel implementaINotifyPropertyChanged
.
Ainda estou reunindo cognitivamente os conceitos do MVVM, então não sei se:
- Você precisa colocar o
INotifyPropertyChanged
no ViewModel para começarCommandSink
a trabalhar - Isso é apenas uma aberração da norma e isso realmente não importa
- Você sempre deve implementar o modelo
INotifyPropertyChanged
e isso é apenas um erro que seria corrigido se isso fosse desenvolvido a partir de um exemplo de código para um aplicativo
Quais foram as experiências de outras pessoas nos projetos MVVM em que você trabalhou?
c#
mvvm
inotifypropertychanged
Edward Tanguay
fonte
fonte
Respostas:
Eu diria exatamente o contrário: eu sempre coloco o meu
INotifyPropertyChanged
no meu ViewModel - você realmente não quer poluir seu modelo com um recurso específico do WPFINotifyPropertyChanged
, como esse material deve estar no ViewModel.Tenho certeza de que outros discordarão, mas é assim que trabalho.
fonte
Eu discordo totalmente do conceito de que o modelo não deve implementar o
INotifyPropertyChanged
. Essa interface não é específica da interface do usuário! Simplesmente informa de uma mudança. De fato, o WPF usa isso fortemente para identificar alterações, mas isso não significa que seja uma interface de interface do usuário. Eu compararia com o seguinte comentário: " Um pneu é um acessório de carro ". Claro que sim, mas bicicletas, ônibus etc. também o usam. Em resumo, não tome essa interface como uma coisa de interface do usuário.Dito isto, isso não significa necessariamente que acredito que o Modelo deva fornecer notificações. De fato, como regra geral, o modelo não deve implementar essa interface, a menos que seja necessário. Na maioria dos casos, em que nenhum dado do servidor é enviado por push para o aplicativo cliente, o modelo pode ficar obsoleto. Mas se estiver ouvindo os dados do mercado financeiro, não vejo por que o modelo não pode implementar a interface. Como exemplo, e se eu tiver uma lógica que não seja da interface do usuário, como um serviço que, quando recebe um preço de compra ou de venda por um determinado valor, emite um alerta (por exemplo, por meio de um email) ou faz um pedido? Esta poderia ser uma possível solução limpa.
No entanto, existem diferentes maneiras de conseguir as coisas, mas eu sempre argumentaria a favor da simplicidade e evitaria redundância.
O que é melhor? Definir eventos em uma coleção ou alterações de propriedade no modelo de visualização e propagá-lo para o modelo ou fazer com que a visualização atualize intrinsecamente o modelo (por meio do modelo de visualização)?
A linha inferior sempre que você vê alguém dizendo que " você não pode fazer isso ou aquilo " é um sinal de que eles não sabem do que estão falando.
Realmente depende do seu caso e, de fato, o MVVM é uma estrutura com muitos problemas e ainda estou para ver uma implementação comum do MVVM em todos os aspectos.
Eu gostaria de ter mais tempo para explicar os vários tipos de MVVM e algumas soluções para problemas comuns - principalmente fornecidos por outros desenvolvedores, mas acho que terei que fazê-lo outra vez.
fonte
INotifyPropertyChanged
faz parte doSystem.ComponentModel
espaço para nome que é " comportamento em tempo de execução e tempo de design de componentes e controles ". NÃO USEINotifyPropertyChanged
em modelos, apenas em modelos de exibição. Link para docs: docs.microsoft.com/en-us/dotnet/api/system.componentmodelNo MV-VM, o ViewModel sempre (o modelo nem sempre) implementa
INotifyPropertyChanged
Confira o Template / Toolkit do projeto MV-VM em http://blogs.msdn.com/llobo/archive/2009/05/01/download-mv-vm-project-template-toolkit.aspx . Ele usa o
DelegateCommand
comando for e deve ser um ótimo modelo inicial para seus projetos MV-VM.fonte
Acho que o MVVM é muito mal nomeado e chamar o ViewModel de ViewModel faz com que muitos percam um recurso importante de uma arquitetura bem projetada, que é um DataController que controla os dados, independentemente de quem estiver tentando tocá-los.
Se você pensa no View-Model como mais um DataController e implementa uma arquitetura em que o DataController é o único item que toca nos dados, você nunca tocaria diretamente nos dados, mas sempre o utilizaria. O DataController é útil para a interface do usuário, mas não necessariamente apenas para a interface do usuário. É para camada de negócios, camada de interface do usuário, etc ...
Você acaba com um modelo como este. Até a empresa só deve tocar nos dados usando o ViewModel. Então seu enigma simplesmente desaparece.
fonte
Depende de como você implementou seu modelo. Minha empresa usa objetos de negócios semelhantes aos objetos CSLA da Lhotka e faz uso extensivo de
INotifyPropertyChanged
todo o modelo de negócios.Nosso mecanismo de validação depende muito de ser notificado de que as propriedades são alteradas por esse mecanismo e funciona muito bem. Obviamente, se você estiver usando uma implementação diferente de objetos de negócios em que a notificação de alterações não seja tão crítica para a operação, poderá ter outros métodos para detectar alterações em seu modelo de negócios.
Também temos modelos de exibição que propagam as alterações do modelo quando necessário, mas os modelos de exibição estão ouvindo as alterações subjacentes do modelo.
fonte
Concordo com a resposta de Paulo, a implementação
INotifyPropertyChanged
em modelos é totalmente aceitável e até sugerida pela Microsoft -Embora seja você quem decide se deseja ou não esse tipo de implementação, lembre-se:
Retirado de - http://msdn.microsoft.com/en-us/library/gg405484(PandP.40).aspx
Já trabalhei em alguns projetos em que não implementamos
INotifyPropertyChanged
nossos modelos e, por isso, enfrentamos muitos problemas; era necessária duplicação desnecessária de propriedades na VM e, ao mesmo tempo, tivemos que atualizar o objeto subjacente (com valores atualizados) antes de passá-los para BL / DL.Você enfrentará problemas especialmente se precisar trabalhar com a coleção de objetos do seu modelo (por exemplo, em uma grade ou lista editável) ou modelos complexos; os objetos de modelo não serão atualizados automaticamente e você precisará gerenciar tudo isso na sua VM.
fonte
Mas, às vezes (como no texto do link da apresentação ), o modelo é serviço, que fornece alguns dados on-line ao aplicativo e é necessário implementar a notificação de que novos dados chegaram ou que os dados foram alterados usando eventos ...
fonte
Eu acho que a resposta é bastante clara se você deseja aderir à MV-VM.
consulte: http://msdn.microsoft.com/en-us/library/gg405484(v=PandP.40).aspx
No padrão MVVM, a visualização encapsula a interface do usuário e qualquer lógica da interface do usuário, o modelo de visualização encapsula a lógica e o estado da apresentação e o modelo encapsula a lógica e os dados de negócios.
fonte
Eu diria no seu ViewModel. Não faz parte do modelo, pois o modelo é independente da interface do usuário. O Modelo deve ser "tudo, exceto negócios agnósticos"
fonte
A implementação do INPC nos modelos pode ser usada se os modelos estiverem claramente expostos no ViewModel. Mas, geralmente, o ViewModel agrupa os modelos são suas próprias classes para reduzir a complexidade do modelo (que não deve ser útil para a ligação). Nesse caso, o INPC deve ser implementado no ViewModel.
fonte
Eu estou usando a
INotifyPropertyChange
interface em um modelo. Na verdade, uma alteração na propriedade do modelo deve ser acionada apenas pela interface do usuário ou pelo cliente externo.Eu notei várias vantagens e desvantagens:
Vantagens
O notificador está no modelo de negócios
Desvantagens
O modelo possui propriedades (quantidade, taxa, comissão, total de direitos). O total da receita é calculado usando a quantidade, taxa e alteração da comissão.
Ao carregar valores de db, o cálculo do total de frieght é chamado 3 vezes (qtd, taxa, comissão). Deveria ser uma vez.
Se rate, qty for atribuído na camada de negócios, novamente o notificador será chamado.
Deve haver uma opção para desativar isso, possivelmente na classe base. No entanto, os desenvolvedores podem se esquecer de fazer isso.
fonte
Eu acho que tudo depende do caso de uso.
Quando você tem um modelo simples com muitas propriedades, pode implementá-lo no INPC. Simplesmente, quero dizer que esse modelo se parece com um POCO .
Se o seu modelo for mais complexo e residir em um domínio de modelo interativo - modelos que fazem referência a modelos, inscrevendo-se em eventos de outros modelos - ter eventos de modelo implementados como INPC é um pesadelo.
Coloque-se na posição de alguma entidade modelo que precisa colaborar com outros modelos. Você tem vários eventos para se inscrever. Todos eles são implementados como INPC. Imagine os manipuladores de eventos que você possui. Uma enorme cascata de cláusulas se e / ou cláusulas de troca.
Outro problema com o INPC. Você deve projetar seus aplicativos para confiar na abstração, não na implementação. Isso geralmente é feito usando interfaces.
Vamos dar uma olhada em 2 implementações diferentes da mesma abstração:
Agora olhe para os dois. O que o IConnectionManagerINPC lhe diz? Que algumas de suas propriedades podem mudar. Você não sabe qual deles. De fato, o design é que apenas o IsConnected muda, pois o restante deles é somente leitura.
Pelo contrário, as intenções de IConnectionManager são claras: "Posso dizer que o valor da minha propriedade IsConnected pode ser alterado".
fonte
Basta usar o
INotifyPropertyChange
no seu viewmodel e não no Model,o modelo geralmente usa o
IDataErrorInfo
para lidar com os erros de validação, portanto, mantenha-se no seu ViewModel e você estará no caminho da MVVM.fonte
Suponha que a referência do objeto em sua visualização seja alterada. Como você notificará todas as propriedades a serem atualizadas para mostrar os valores corretos? Chamar
OnPropertyChanged
na sua visualização todas as propriedades do objeto é um lixo para o meu ponto de vista.Então, o que eu faço é deixar que o próprio objeto para notificar ninguém quando um valor em uma propriedade mudanças, e na minha opinião, eu uso ligações como
Object.Property1
,Object.Property2
e sobre. Dessa forma, se eu apenas quiser alterar o objeto que atualmente é mantido em minha opinião, apenas o façoOnPropertyChanged("Object")
.Para evitar centenas de notificações durante o carregamento de objetos, tenho um indicador booleano privado que o defino como true durante o carregamento, verificado a partir do objeto
OnPropertyChanged
e não faz nada.fonte
Normalmente, o ViewModel implementará o
INotifyPropertyChanged
. O modelo pode ser qualquer coisa (arquivo xml, banco de dados ou mesmo objeto). Modelo é usado para fornecer os dados ao modelo de exibição, que se propaga para a exibição.Veja aqui
fonte
imho Eu acho que o viewmodel implementa
INotifyPropertyChange
e o modelo pode usar a notificação em um "nível" diferente.por exemplo, com algum serviço de documento e um objeto de documento, você tem um evento documentChanged que um modelo de exibição ouve para limpar e reconstruir a exibição. No modelo de visualização de edição, você tem uma alteração de propriedade para as propriedades do documento para suportar as visualizações. Se o serviço fizer muito com o documento ao salvar (atualizando data de alteração, último usuário e assim por diante), é fácil obter uma sobrecarga de eventos alterados por propriedade e apenas um documento alterado é suficiente.
Mas se você usar
INotifyPropertyChange
em seu modelo, acho que é uma boa prática retransmiti-lo em seu viewmodel, em vez de assiná-lo diretamente em seu view. Nesse caso, quando os eventos mudam no seu modelo, você só precisa alterar o modelo de exibição e a exibição permanece intocada.fonte
Todas as propriedades, que estão vinculadas à minha visualização, estão nos meus ViewModel (s). Portanto, eles devem implementar a interface INotifyPropertyChanged. Portanto, o modo de exibição recebe todas as alterações.
[Usando o kit de ferramentas MVVM Light, eu os deixei herdar do ViewModelBase.]
O Modelo mantém a lógica de negócios, mas não tem nada a ver com a exibição. Portanto, não há necessidade da interface INotifyPropertyChanged.
fonte