147 votes

Bons exemples du modèle MVVM

Je suis actuellement en train de travailler avec Microsoft MVVM modèle et de trouver le manque de détails, des exemples frustrant. Inclus ContactBook exemple montre que très peu de la gestion de Commande et le seul autre exemple que j'ai trouvé est à partir d'un article de MSDN Magazine où les concepts sont similaires, mais utilise une approche légèrement différente et toujours le manque de n'importe quelle complexité. Il n'existe aucun décent MVVM exemples, au moins, de base les opérations CRUD et de boîte de dialogue/la commutation de contenu?


Chacun suggestions ont été vraiment utile et je vais commencer à compiler une liste de bonnes ressources

Cadres/Modèles

Des Articles Utiles

Screencasts

Bibliothèques Supplémentaires

60voto

Egor Points 1318

Il n'est malheureusement pas un grand MVVM exemple d'application qui fait tout, et il ya beaucoup d'approches différentes de faire les choses. Tout d'abord, vous voudrez peut-être obtenir familier avec celui de l'application des cadres (Prism est un choix décent), parce qu'ils vous fournissent des outils pratiques comme l'injection de dépendance, commandant, agrégation d'événements, etc facilement essayer différents modèles qui vous conviennent.

Le prisme de presse:
http://www.codeplex.com/CompositeWPF

Il comprend un bon exemple d'application (stock trader) avec un lot de petits exemples et comment. Au moins c'est une bonne démonstration de plusieurs sous-modèles que les gens utilisent pour faire MVVM fonctionnent réellement. Ils ont des exemples pour les deux CRUD et les boîtes de dialogue, je crois.

Prism n'est pas nécessairement pour chaque projet, mais c'est une bonne chose pour se familiariser avec.

CRUD: Cette partie est assez facile, WPF deux façon de liaisons de le rendre vraiment facile pour modifier la plupart des données. Le vrai truc est de fournir un modèle qui le rend facile à mettre en place l'INTERFACE utilisateur. À tout le moins, vous voulez vous assurer que votre ViewModel (ou business object) implémente INotifyPropertyChanged pour prendre en charge la liaison et vous pouvez lier les propriétés directement à des contrôles d'INTERFACE utilisateur, mais vous pouvez aussi mettre en oeuvre IDataErrorInfo pour la validation. En règle générale, si vous utilisez une sorte de solution ORM configuration de CRUD est un composant logiciel enfichable.

Cet article montre simples opérations crud: http://dotnetslackers.com/articles/wpf/WPFDataBindingWithLINQ.aspx

Il est construit sur LinqToSql, mais c'est sans importance pour l'exemple - tout ce qui est important, c'est que votre entreprise objets de mettre en oeuvre INotifyPropertyChanged (dont les classes générées par LinqToSql faire). MVVM n'est pas le point de cet exemple, mais je ne pense pas que c'est important dans ce cas.

Cet article montre 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 ORM solutions de générer des classes qui implémentent déjà IDataErrorInfo et généralement fournir un mécanisme pour le faire, il est facile d'ajouter des règles de validation.

La plupart du temps, vous pouvez prendre un objet(modèle) créé par un ORM et l'envelopper dans un ViewModel qu'il détient et des commandes pour enregistrer/effacer - et vous êtes prêt à lier l'INTERFACE utilisateur directement les propriétés du modèle.

Le point de vue de ressembler à quelque chose comme ceci (ViewModel a une propriété Item qui détient le modèle, comme une classe créée dans le ORM):

<StackPanel>
   <StackPanel DataContext=Item>
      <TextBox Text="{Binding FirstName, Mode=TwoWay, ValidatesOnDataErrors=True}" />
      <TextBox Text="{Binding LastName, Mode=TwoWay, ValidatesOnDataErrors=True}" />
   </StackPanel>
   <Button Command="{Binding SaveCommand}" />
   <Button Command="{Binding CancelCommand}" />
</StackPanel>

Boîtes de dialogue: Les boîtes de dialogue et MVVM sont un peu délicat. Je préfère utiliser une saveur du Médiateur approche avec les boîtes de dialogue, vous pouvez lire un peu plus à ce sujet dans ce StackOverflow question:
WPF MVVM exemple de boîte de dialogue

Mon approche habituelle, ce qui n'est pas tout à fait classique MVVM, peuvent être résumées comme suit:

Une classe de base pour un dialogue ViewModel qui expose les commandes pour valider et annuler des actions, un événement permet à la vue de savoir qu'un dialogue est prêt à être fermé, et tout le reste vous aurez besoin de toutes vos boîtes de dialogue.

Une vue générique pour votre boîte de dialogue, ce qui peut être une fenêtre, ou une coutume "modal" superposition de contrôle de type. En son cœur, c'est un présentateur qui nous décharge de ce dernier, et il gère le câblage pour la fermeture de la fenêtre (par exemple sur des données de changement de contexte, vous pouvez vérifier si la nouvelle ViewModel est hérité de votre classe de base, et si elle l'est, abonnez-vous à la proximité de l'événement (le gestionnaire d'affecter la boîte de dialogue résultat). Si vous fournissent une solution universelle à proximité de la fonctionnalité (le bouton X, par exemple), vous devriez assurez-vous d'exécuter pertinentes de la commande fermer dans le ViewModel.

Quelque part vous avez besoin de fournir des modèles de données pour votre Viewmodel, ils peuvent être très simple, en particulier depuis, vous avez probablement une vue pour chaque boîte de dialogue encapsulé dans une commande distincte. Le modèle de données par défaut pour un ViewModel serait alors ressembler à ceci:

<DataTemplate DataType="{x:Type vmodels:AddressEditViewModel}>
   <views:AddressEditView DataContext={Binding} />
</DataTemplate>

La boîte de dialogue vue doit avoir accès à ceux-ci, parce que sinon ça ne savez pas comment montrer le ViewModel, de côté par le partage de l'INTERFACE de dialogue de son contenu sont essentiellement ceci:

<ContentControl Content={Binding} />

L'implicite de données de modèle de carte de la vue du modèle, mais qui se lance?

Ce n'est pas si mvvm partie. Une façon de le faire est d'utiliser un événement mondial. Ce que je pense, c'est une meilleure chose à faire est d'utiliser un agrégateur d'événements type d'installation, fournis par le biais de l'injection de dépendances - de cette façon, l'événement est mondial à un conteneur, pas l'ensemble de l'application. Prism utilise l'unité cadre de contenants, de la sémantique et de l'injection de dépendance, et dans l'ensemble j'aime l'Unité tout à fait un peu.

Habituellement, il a un sens de la racine de la fenêtre pour vous abonner à cette manifestation, il peut ouvrir la boîte de dialogue et l'ensemble de ses données de contexte pour le ViewModel qui est transmis avec une élévation de l'événement.

Cette mise en place de cette manière permet de ViewModels demander l'application pour ouvrir un dialogue et de répondre aux actions de l'utilisateur sans rien connaître de l'INTERFACE utilisateur, donc, pour la plupart, le MVVM-ness reste complet.

Il ya des moments, cependant, où l'INTERFACE est de soulever les boîtes de dialogue, ce qui peut rendre les choses un peu plus compliqué. Considérez par exemple, si la boîte de dialogue position dépend de l'emplacement du bouton qui s'ouvre. Dans ce cas, vous devez avoir une INTERFACE utilisateur spécifique info lorsque vous demander une boîte de dialogue ouvrir. J'ai en général de créer une catégorie distincte qui est titulaire d'un ViewModel et de l'INTERFACE utilisateur informations. Malheureusement, certains de couplage semble inévitable.

Le Pseudo-code d'un gestionnaire de bouton qui déclenche une boîte de dialogue dans laquelle les besoins de la position de l'élément de données:

ButtonClickHandler(sender, args){
    var vm = DataContext as ISomeDialogProvider; // check for null
    var ui_vm = new ViewModelContainer();
    // assign margin, width, or anything else that your custom dialog might require
    ...
    ui_vm.ViewModel = vm.SomeDialogViewModel; // or .GetSomeDialogViewModel()
    // raise the dialog show event
}

La boîte de dialogue vue de les lier à des données de position, et de transmettre le contenu de l'ViewModel à l'intérieur de la ContentControl. Le ViewModel lui-même ne sait rien à propos de l'INTERFACE utilisateur.

En général, je n'utilise pas l' DialogResult retour de la propriété de l' ShowDialog() méthode ou attendre le fil à bloc jusqu'à ce que la boîte de dialogue est fermée. Un non-standard de la boîte de dialogue modale ne fonctionne pas toujours comme ça, et dans un environnement de composite souvent, vous n'avez pas vraiment envie d'un gestionnaire d'événements pour bloquer comme ça de toute façon. Je préfère laisser le Viewmodel traiter avec cela, le créateur d'un ViewModel peut s'abonner à ses événements pertinents, définir s'engager/d'annuler les méthodes, etc, donc il n'est pas nécessaire de s'appuyer sur ce mécanisme d'INTERFACE utilisateur.

Ainsi, au lieu de ce flux:

// in code behind
var result = somedialog.ShowDialog();
if (result == ...

J'utilise:

// in view model
var vm = new SomeDialogViewModel(); // child view model
vm.CommitAction = delegate { this.DoSomething(vm); } // what happens on commit 
vm.CancelAction = delegate { this.DoNothing(vm); } // what happens on cancel/close (optional)
// raise dialog request event on the container

Je préfère de cette façon parce que la plupart de mes boîtes de dialogue sont non-bloquant pseudo-modale des contrôles et de le faire de cette façon semble plus simple que de travailler autour d'elle. Facile de test de l'unité.

6voto

nportelli Points 2350

Jason Dolinger fait une bonne screencast de MVVM. Comme Egor mentionné, il n'est pas un bon exemple. Ils sont tous sur. La plupart sont de bons MVVM exemples, mais pas quand vous obtenez dans des questions complexes. Chacun a son propre chemin. Laurent Bugnion a 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 aussi un bon exemple. Paul Stovel a un bon post qui explique beaucoup trop avec son Magellan cadre.

3voto

Andy S Points 3975

Avez-vous regardé Caliburn? L’échantillon de ContactManager a beaucoup de bonnes choses dedans. Les échantillons WPF génériques fournissent également une bonne vue d’ensemble des commandes. La documentation est assez bonne et les forums sont actifs. Recommandé !

2voto

Reed Copsey Points 315315

L’exemple de projet dans le cadre de Cinch montre CRUD de base et les outils de navigation. C’est un assez bon exemple d’utilisation de MVVM et comprend un article multi-partie expliquant son utilisation et les motivations.

2voto

Scott Whitlock Points 8172

J'ai également partagé votre frustration. Je suis en train d'écrire une application et j'ai eu ces 3 exigences:

  • Extensible
  • WPF avec MVVM
  • Compatible avec la GPL exemples

Tout ce que je trouve ont été de pièces et de morceaux, donc j'ai simplement commencé à écrire du mieux que je pouvais. Après je m'y suis mise un peu, j'ai réalisé il y a peut être d'autres personnes (comme toi) qui pourraient utiliser une application de référence, j'ai donc refait le générique des trucs en WPF/MVVM cadre d'application et publié sous la licence LGPL. Je la nomme de caisse à savon de Base. Si vous allez à la page de téléchargement, vous verrez qu'il est livré avec une petite démo de l'application, et le code source de la démo de l'application est également disponible pour le téléchargement. J'espère que vous trouverez très utile. Aussi, écrivez-moi à scott {at} soapboxautomation.com si vous voulez plus d'info.

EDIT: Également posté un CodeProject article expliquant comment il fonctionne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X