Je travaille actuellement avec le modèle Microsoft MVVM et je trouve le manque d'exemples détaillés frustrant. L'exemple ContactBook inclus montre très peu de gestion des commandes et le seul autre exemple que j'ai trouvé provient d'un article de MSDN Magazine où les concepts sont similaires mais utilisent une approche légèrement différente et manquent encore de complexité. Existe-t-il des exemples MVVM décents qui montrent au moins les opérations CRUD de base et la commutation de dialogue / contenu?
Les suggestions de chacun ont été vraiment utiles et je vais commencer à compiler une liste de bonnes ressources
Cadres / modèles
Articles utiles
- Applications WPF avec le modèle de conception Model-View-ViewModel
- Validation des données dans .NET 3.5
- Utilisation d'un ViewModel pour fournir des messages d'erreur de validation significatifs
- Validation de ViewModel et de modèle basée sur l'action
- Dialogues
- Liaisons de commandes dans MVVM
- Plus qu'un simple MVC pour WPF
- Exemple d'application MVVM + Mediator
Screencasts
Bibliothèques supplémentaires
- Implémentation améliorée du modèle Mediator de WPF Disciples (je le recommande vivement pour les applications qui ont une navigation plus complexe)
- MVVM Light Toolkit Messenger
Réponses:
Malheureusement, il n'y a pas un seul excellent exemple d'application MVVM qui fasse tout, et il existe de nombreuses approches différentes pour faire les choses. Tout d'abord, vous voudrez peut-être vous familiariser avec l'un des frameworks d'application (Prism est un choix décent), car ils vous fournissent des outils pratiques tels que l'injection de dépendances, la commande, l'agrégation d'événements, etc. pour essayer facilement différents modèles qui vous conviennent. .
La version prisme:
http://www.codeplex.com/CompositeWPF
Il comprend un exemple d'application assez décent (le négociant en actions) ainsi que de nombreux exemples plus petits et comment faire. À tout le moins, c'est une bonne démonstration de plusieurs sous-modèles courants que les gens utilisent pour faire fonctionner MVVM. Ils ont des exemples de CRUD et de dialogues, je crois.
Prism n'est pas nécessairement pour tous les projets, mais c'est une bonne chose à connaître.
CRUD: Cette partie est assez simple, les liaisons bidirectionnelles WPF facilitent la modification de la plupart des données. Le vrai truc est de fournir un modèle qui facilite la configuration de l'interface utilisateur. À tout le moins, vous voulez vous assurer que votre ViewModel (ou objet métier) est implémenté
INotifyPropertyChanged
pour prendre en charge la liaison et que vous pouvez lier les propriétés directement aux contrôles de l'interface utilisateur, mais vous pouvez également implémenterIDataErrorInfo
pour la validation. En règle générale, si vous utilisez une sorte de solution ORM, la configuration de CRUD est un jeu d'enfant.Cet article présente des opérations simples de crud: http://dotnetslackers.com/articles/wpf/WPFDataBindingWithLINQ.aspx
Il est construit sur LinqToSql, mais cela n'est pas pertinent pour l'exemple - tout ce qui est important est que vos objets métier implémentent
INotifyPropertyChanged
(ce que font les classes générées par LinqToSql). MVVM n'est pas le point de cet exemple, mais je ne pense pas que cela compte dans ce cas.Cet article illustre la validation des données
http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx
Encore une fois, la plupart des solutions ORM génèrent des classes qui implémentent déjà
IDataErrorInfo
et fournissent généralement un mécanisme pour faciliter l'ajout de règles de validation personnalisées.La plupart du temps, vous pouvez prendre un objet (modèle) créé par un ORM et l'envelopper dans un ViewModel qui le contient et des commandes pour enregistrer / supprimer - et vous êtes prêt à lier l'interface utilisateur directement aux propriétés du modèle.
La vue ressemblerait à quelque chose comme ceci (ViewModel a une propriété
Item
qui contient le modèle, comme une classe créée dans l'ORM):Dialogues: les dialogues et MVVM sont un peu compliqués. Je préfère utiliser une saveur de l'approche Mediator avec des dialogues, vous pouvez en savoir un peu plus à ce sujet dans cette question StackOverflow:
Exemple de dialogue WPF MVVM
Mon approche habituelle, qui n'est pas tout à fait classique MVVM, peut se résumer comme suit:
Une classe de base pour un ViewModel de dialogue qui expose des commandes pour les actions de validation et d'annulation, un événement pour informer la vue qu'une boîte de dialogue est prête à être fermée, et tout ce dont vous aurez besoin dans toutes vos boîtes de dialogue.
Une vue générique pour votre boîte de dialogue - cela peut être une fenêtre ou un contrôle de type de superposition "modal" personnalisé. En son cœur, c'est un présentateur de contenu dans lequel nous vidons le viewmodel, et il gère le câblage pour fermer la fenêtre - par exemple, lors du changement de contexte de données, vous pouvez vérifier si le nouveau ViewModel est hérité de votre classe de base, et si c'est le cas, abonnez-vous à l'événement de fermeture pertinent (le gestionnaire attribuera le résultat de la boîte de dialogue). Si vous fournissez une autre fonctionnalité de fermeture universelle (le bouton X, par exemple), vous devez également vous assurer d'exécuter la commande de fermeture appropriée sur le ViewModel.
Quelque part, vous devez fournir des modèles de données pour vos ViewModels, ils peuvent être très simples, d'autant plus que vous avez probablement une vue pour chaque boîte de dialogue encapsulée dans un contrôle séparé. Le modèle de données par défaut pour un ViewModel ressemblerait alors à ceci:
La vue de la boîte de dialogue doit y avoir accès, car sinon elle ne saura pas comment afficher le ViewModel, à part l'interface utilisateur de la boîte de dialogue partagée, son contenu est essentiellement le suivant:
Le modèle de données implicite mappera la vue sur le modèle, mais qui le lance?
C'est la partie pas si mvvm. Une façon de le faire est d'utiliser un événement global. Ce que je pense qu'il vaut mieux faire est d'utiliser une configuration de type d'agrégateur d'événements, fournie par injection de dépendances - de cette façon, l'événement est global à un conteneur, pas à l'ensemble de l'application. Prism utilise le cadre d'unité pour la sémantique des conteneurs et l'injection de dépendances, et dans l'ensemble, j'aime beaucoup Unity.
Habituellement, il est logique que la fenêtre racine s'abonne à cet événement - elle peut ouvrir la boîte de dialogue et définir son contexte de données sur le ViewModel qui est transmis avec un événement déclenché.
Configurer cela de cette manière permet à ViewModels de demander à l'application d'ouvrir une boîte de dialogue et de répondre aux actions de l'utilisateur sans rien savoir sur l'interface utilisateur, de sorte que la MVVM-ness reste pour la plupart complète.
Il y a des moments, cependant, où l'interface utilisateur doit augmenter les dialogues, ce qui peut rendre les choses un peu plus délicates. Considérez par exemple si la position de la boîte de dialogue dépend de l'emplacement du bouton qui l'ouvre. Dans ce cas, vous devez disposer d'informations spécifiques à l'interface utilisateur lorsque vous demandez l'ouverture d'une boîte de dialogue. Je crée généralement une classe distincte qui contient un ViewModel et des informations d'interface utilisateur pertinentes. Malheureusement, un certain couplage y paraît inévitable.
Pseudo code d'un gestionnaire de bouton qui déclenche une boîte de dialogue nécessitant des données de position d'élément:
La vue de boîte de dialogue se liera aux données de position et transmettra le ViewModel contenu à l'intérieur
ContentControl
. Le ViewModel lui-même ne sait toujours rien de l'interface utilisateur.En général, je n'utilise pas la
DialogResult
propriété return de laShowDialog()
méthode ou je m'attends à ce que le thread se bloque jusqu'à ce que la boîte de dialogue soit fermée. Une boîte de dialogue modale non standard ne fonctionne pas toujours comme ça, et dans un environnement composite, vous ne voulez souvent pas vraiment qu'un gestionnaire d'événements se bloque comme ça de toute façon. Je préfère laisser les ViewModels s'occuper de cela - le créateur d'un ViewModel peut s'abonner à ses événements pertinents, définir des méthodes de validation / d'annulation, etc., il n'est donc pas nécessaire de s'appuyer sur ce mécanisme d'interface utilisateur.Donc, au lieu de ce flux:
J'utilise:
Je le préfère ainsi car la plupart de mes dialogues sont des contrôles pseudo-modaux non bloquants et le faire de cette façon semble plus simple que de contourner cela. Test unitaire facile également.
la source
Jason Dolinger a fait un bon screencast de MVVM. Comme Egor l'a mentionné, il n'y a pas un seul bon exemple. Ils sont partout. La plupart sont de bons exemples MVVM, mais pas lorsque vous rencontrez des problèmes complexes. Chacun a sa manière. Laurent Bugnion a également un bon moyen de communiquer entre les viewmodels. http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx Cinch est également un bon exemple. Paul Stovel a un bon article qui en explique aussi beaucoup avec son framework Magellan.
la source
Avez-vous regardé Caliburn ? L'exemple ContactManager contient beaucoup de bonnes choses. Les exemples WPF génériques fournissent également un bon aperçu des commandes. La documentation est assez bonne et les forums sont actifs. Conseillé!
la source
J'ai trouvé celui-ci utile. A du code aussi.
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
la source
Ici, j'ajoute le lien d'une application WPF (Inventory Management App) qui utilise l' architecture MVVM conçue par moi.
Son interface utilisateur est géniale. https://github.com/shivam01990/InventoryManagement
la source
L'exemple de projet dans le framework Cinch montre les outils de base CRUD et de navigation. C'est un assez bon exemple d'utilisation de MVVM, et comprend un article en plusieurs parties expliquant son utilisation et ses motivations.
la source
J'ai également partagé votre frustration. J'écris une candidature et j'avais ces 3 exigences:
Tout ce que j'ai trouvé était des fragments, alors j'ai commencé à l'écrire du mieux que je pouvais. Une fois que j'y suis entré un peu, j'ai réalisé qu'il pourrait y avoir d'autres personnes (comme vous) qui pourraient utiliser une application de référence, alors j'ai refactoré le contenu générique dans un cadre d'application WPF / MVVM et l'ai publié sous la LGPL. Je l'ai nommé SoapBox Core . Si vous accédez à la page de téléchargement, vous verrez qu'elle est livrée avec une petite application de démonstration, et le code source de cette application de démonstration est également disponible en téléchargement. J'espère que vous trouverez cela utile. Aussi, écrivez-moi à scott {at} soapboxautomation.com si vous voulez plus d'informations.
EDIT : a également publié un article CodeProject expliquant son fonctionnement.
la source
J'ai écrit un simple exemple MVVM à partir de zéro sur un projet de code, voici le lien MVVM WPF étape par étape . Il part d'une architecture simple à 3 couches et vous permet d'utiliser un cadre comme PRISM.
la source
Même moi, j'ai partagé la frustration jusqu'à ce que je prenne l'affaire en main. J'ai lancé IncEditor.
IncEditor ( http://inceditor.codeplex.com ) est un éditeur qui tente de présenter aux développeurs WPF, MVVM et MEF. Je l'ai commencé et j'ai réussi à obtenir des fonctionnalités telles que la prise en charge du «thème». Je ne suis pas expert en WPF, MVVM ou MEF, donc je ne peux pas y mettre beaucoup de fonctionnalités. Je vous demande sincèrement de l'améliorer afin que les fous comme moi puissent mieux le comprendre.
la source