Atualmente, estou trabalhando com o modelo Microsoft MVVM e considero frustrante a falta de exemplos detalhados. O exemplo incluído do ContactBook mostra muito pouco tratamento de comandos e o único outro exemplo que encontrei é de um artigo da MSDN Magazine em que os conceitos são semelhantes, mas usam uma abordagem um pouco diferente e ainda carecem de complexidade. Existem exemplos decentes de MVVM que mostram pelo menos operações básicas CRUD e troca de diálogo / conteúdo?
As sugestões de todos foram realmente úteis e começarei a compilar uma lista de bons recursos
Estruturas / Modelos
Artigos úteis
- Aplicativos WPF com o padrão de design Model-View-ViewModel
- Validação de dados no .NET 3.5
- Usando um ViewModel para fornecer mensagens de erro significativas de validação
- Validação de ViewModel e Model com base em ação
- Diálogos
- Ligações de comando no MVVM
- Mais do que apenas o MVC para WPF
- Exemplo de Aplicação MVVM + Mediador
Screencasts
Bibliotecas adicionais
- Implementação aprimorada do Padrão do Mediador dos Discípulos do WPF (eu recomendo isso para aplicativos com navegação mais complexa)
- MVVM Light Toolkit Messenger
Respostas:
Infelizmente, não há um ótimo exemplo de aplicativo MVVM que faça tudo, e há várias abordagens diferentes para fazer as coisas. Primeiro, você pode se familiarizar com uma das estruturas de aplicativos existentes no mercado (o Prism é uma escolha decente), porque elas fornecem ferramentas convenientes, como injeção de dependência, comando, agregação de eventos etc. para experimentar facilmente diferentes padrões adequados a você. .
O lançamento do prisma:
http://www.codeplex.com/CompositeWPF
Ele inclui um aplicativo de exemplo bastante decente (o corretor da bolsa), juntamente com muitos exemplos menores e como fazer. No mínimo, é uma boa demonstração de vários sub-padrões comuns que as pessoas usam para fazer o MVVM realmente funcionar. Eles têm exemplos para CRUD e diálogos, acredito.
O prisma não é necessariamente para todos os projetos, mas é bom se familiarizar.
CRUD: Esta parte é bastante fácil, as ligações bidirecionais do WPF facilitam a edição da maioria dos dados. O verdadeiro truque é fornecer um modelo que facilite a configuração da interface do usuário. No mínimo, você deseja garantir que seu ViewModel (ou objeto de negócios) seja implementado
INotifyPropertyChanged
para oferecer suporte à ligação e que você possa vincular propriedades diretamente aos controles da interface do usuário, mas também poderá implementarIDataErrorInfo
para validação. Normalmente, se você usar algum tipo de solução ORM, configurar o CRUD é muito fácil.Este artigo demonstra operações simples de crud: http://dotnetslackers.com/articles/wpf/WPFDataBindingWithLINQ.aspx
Ele é construído no LinqToSql, mas isso é irrelevante para o exemplo - tudo o que é importante é que seus objetos de negócios implementem
INotifyPropertyChanged
(que classes geradas pelo LinqToSql fazem). MVVM não é o objetivo desse exemplo, mas acho que não importa nesse caso.Este artigo demonstra a validação de dados
http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx
Novamente, a maioria das soluções ORM gera classes que já implementam
IDataErrorInfo
e geralmente fornecem um mecanismo para facilitar a adição de regras de validação personalizadas.Na maioria das vezes, você pode pegar um objeto (modelo) criado por algum ORM e envolvê-lo em um ViewModel que o contém e comandos para salvar / excluir - e você está pronto para vincular a interface do usuário diretamente às propriedades do modelo.
A visualização ficaria assim: (ViewModel possui uma propriedade
Item
que mantém o modelo, como uma classe criada no ORM):Diálogos: Diálogos e MVVM são um pouco complicados. Eu prefiro usar um pouco da abordagem do Mediador com diálogos, você pode ler um pouco mais sobre isso nesta pergunta StackOverflow:
Exemplo de diálogo WPF MVVM
Minha abordagem usual, que não é bem clássica do MVVM, pode ser resumida da seguinte forma:
Uma classe base para um ViewModel da caixa de diálogo que expõe comandos para ações de confirmação e cancelamento, um evento para que a visualização saiba que uma caixa de diálogo está pronta para ser fechada e o que mais você precisar em todas as suas caixas de diálogo.
Uma exibição genérica para sua caixa de diálogo - pode ser uma janela ou um controle de tipo de sobreposição "modal" personalizado. No fundo, é um apresentador de conteúdo no qual despejamos o modelo de exibição e ele lida com a fiação para fechar a janela - por exemplo, na alteração do contexto de dados, você pode verificar se o novo ViewModel é herdado da sua classe base e, se for, inscreva-se no evento de fechamento relevante (o manipulador atribuirá o resultado do diálogo). Se você fornecer uma funcionalidade de fechamento universal alternativa (o botão X, por exemplo), certifique-se de executar o comando de fechamento relevante no ViewModel também.
Em algum lugar em que você precisa fornecer modelos de dados para seus ViewModels, eles podem ser muito simples, especialmente porque você provavelmente tem uma visão para cada caixa de diálogo encapsulada em um controle separado. O modelo de dados padrão para um ViewModel ficaria assim:
A visualização da caixa de diálogo precisa ter acesso a eles, porque, caso contrário, não saberá como exibir o ViewModel, além da interface do usuário da caixa de diálogo compartilhada, seu conteúdo é basicamente o seguinte:
O modelo de dados implícito mapeará a visualização para o modelo, mas quem a inicia?
Esta é a parte não tão mvvm. Uma maneira de fazer isso é usar um evento global. O que eu acho que é a melhor coisa a fazer é usar uma configuração do tipo agregador de eventos, fornecida por injeção de dependência - dessa forma, o evento é global para um contêiner, não para o aplicativo inteiro. O Prism usa a estrutura unity para semântica de contêineres e injeção de dependência, e no geral eu gosto bastante do Unity.
Geralmente, faz sentido que a janela raiz assine esse evento - ela pode abrir a caixa de diálogo e definir seu contexto de dados para o ViewModel que é passado com um evento gerado.
A configuração dessa maneira permite que o ViewModels solicite ao aplicativo que abra uma caixa de diálogo e responda às ações do usuário sem saber nada sobre a interface do usuário, de modo que a MVVM-ness permaneça completa.
Há momentos, no entanto, em que a interface do usuário precisa aumentar as caixas de diálogo, o que pode tornar as coisas um pouco mais complicadas. Considere, por exemplo, se a posição da caixa de diálogo depende da localização do botão que a abre. Nesse caso, você precisa ter algumas informações específicas da interface do usuário ao solicitar uma caixa de diálogo aberta. Geralmente, crio uma classe separada que contém um ViewModel e algumas informações relevantes da interface do usuário. Infelizmente, alguns acoplamentos parecem inevitáveis lá.
Pseudo-código de um manipulador de botão que gera uma caixa de diálogo que precisa de dados de posição do elemento:
A visualização da caixa de diálogo será vinculada aos dados da posição e passará o ViewModel contido para o interior
ContentControl
. O ViewModel em si ainda não sabe nada sobre a interface do usuário.Em geral, eu não uso a
DialogResult
propriedade return doShowDialog()
método ou espero que o thread bloqueie até que a caixa de diálogo seja fechada. Um diálogo modal não-padrão nem sempre funciona assim e, em um ambiente composto, muitas vezes você realmente não quer que um manipulador de eventos bloqueie assim. Prefiro deixar que os ViewModels lidem com isso - o criador de um ViewModel pode se inscrever em seus eventos relevantes, definir métodos de confirmação / cancelamento, etc., para que não haja necessidade de confiar nesse mecanismo da interface do usuário.Então, em vez deste fluxo:
Eu uso:
Eu prefiro assim, porque a maioria dos meus diálogos são controles pseudo-modais sem bloqueio e fazê-lo dessa maneira parece mais direto do que contornar isso. Fácil de testar também.
fonte
Jason Dolinger fez um bom screencast do MVVM. Como Egor mencionou, não há um bom exemplo. Eles acabaram. Muitos são bons exemplos de MVVM, mas não quando você se depara com problemas complexos. Todo mundo tem seu próprio caminho. Laurent Bugnion também tem uma boa maneira de se comunicar entre os modelos de exibição. http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx O Cinch também é um bom exemplo. Paul Stovel tem um bom post que explica muito também com sua estrutura Magellan.
fonte
Você já viu Caliburn ? A amostra do ContactManager contém muitas coisas boas. As amostras WPF genéricas também fornecem uma boa visão geral dos comandos. A documentação é bastante boa e os fóruns estão ativos. Recomendado!
fonte
Achei este útil. Tem código também.
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
fonte
Aqui estou adicionando o link de um aplicativo WPF (Inventory Management App) que usa a arquitetura MVVM projetada por mim.
Sua interface do usuário é incrível. https://github.com/shivam01990/InventoryManagement
fonte
O projeto de amostra na estrutura Cinch mostra ferramentas básicas de CRUD e navegação. É um exemplo bastante bom do uso do MVVM e inclui um artigo com várias partes explicando seu uso e motivações.
fonte
Eu também compartilhei sua frustração. Estou escrevendo um aplicativo e tinha esses 3 requisitos:
Tudo o que encontrei foram pedaços, então comecei a escrever da melhor maneira possível. Depois que entrei um pouco nisso, percebi que poderia haver outras pessoas (como você) que poderiam usar um aplicativo de referência, então refatorei o material genérico em uma estrutura de aplicativo WPF / MVVM e a liberei sob a LGPL. Eu o chamei SoapBox Core . Se você for para a página de downloads, verá que ele vem com um pequeno aplicativo de demonstração, e o código-fonte desse aplicativo de demonstração também está disponível para download. Espero que você ache isso útil. Além disso, envie um e-mail para scott {at} soapboxautomation.com se você quiser mais informações.
EDIT : Também postou um artigo do CodeProject explicando como funciona.
fonte
Eu escrevi um exemplo simples do MVVM do zero no projeto de código, aqui está o link MVVM WPF passo a passo . Começa a partir de uma arquitetura simples de 3 camadas e gradua você para usar alguma estrutura como o PRISM.
fonte
Até eu compartilhei a frustração até tomar o assunto em minhas mãos. Comecei o IncEditor.
O IncEditor ( http://inceditor.codeplex.com ) é um editor que tenta apresentar aos desenvolvedores o WPF, MVVM e MEF. Eu o iniciei e consegui obter algumas funcionalidades como suporte ao 'tema'. Como não sou especialista em WPF, MVVM ou MEF, não posso colocar muita funcionalidade nele. Faço um pedido sincero a vocês para que melhorem, para que malucos como eu possam entender melhor.
fonte