2008-11-24 10 views
7

Je suis en train de mettre en œuvre MVP/M-V-VM dans WPF et j'ai de la chance jusqu'à maintenant. Cependant, je ne vois pas comment ce modèle supporte l'implémentation de boîtes de dialogue Modal. J'ai dérivé mon travail de Crack.NET (http://www.codeplex.com/cracknetproject) pour apprendre comment cela fonctionne.Boîtes de dialogue Model-View-Presenter et Modal .... Comment?

J'ai une vue ShellView (qui est juste XAML) qui a un menu dessus. Le menu se lie à une commande dans le ShellModelView qui dit "EditPreferences". ShellModelView implémente l'ICommand pour EditPreferences et ici nous voulons mettre en place une boîte de dialogue pour permettre à l'utilisateur de modifier les préférences pour l'application.

Plusieurs problèmes ici: 1. ShellModelView ne fait pas référence à ShellView pour que le dialogue soit correctement parent. ShellModelView est le DataContext de ShellView mais je ne vois pas de référence arrière configurée. 2. ShellModelView ne devrait pas charger l'interface utilisateur explicite de toute façon. Alors, quel est le modèle d'interaction approprié ici? 3. Comment puis-je créer mon PreferencesDialog afin qu'il soit correctement séparé entre la logique et la vue? PreferencesDialog lui-même doit être une fenêtre afin que vous puissiez appeler ShowDialog dessus, mais cela signifie que vous avez besoin d'une référence à la fenêtre (par exemple View) afin de l'instancier. Idéalement, je devrais être capable de tester le code/validation dans PreferencesDialog sans instancier la vue (en utilisant une vue Mock peut-être?).

Répondre

1

Vous aurez besoin d'un contrôleur dans votre boîtier. Le contrôleur devrait être en charge de montrer la fenêtre de dialogue de préférence.

Comme je peux l'imaginer, le contrôleur devrait être responsable de la création de l'objet DataContext de ShellModelView et de la vue de liaison. Le contrôleur devrait également être responsable de la gestion de l'exécution des commandes de EditPreferences. Dans la logique d'exécution, le contrôleur crée un nouveau PreferencesDialog et son modèle de vue correspondant.

Vous pouvez trouver des modèles similaires dans Prism si vous ne l'avez pas déjà fait. Vous pouvez également réutiliser la DelegateCommand fournie ici :)

6

Peut-être que ce n'est pas la bonne façon de le regarder, mais c'est l'approche que je prends avec M-V-VM dans WPF. L'ouverture des fenêtres et des boîtes de dialogue ou une vue "EditPreferences" sont des fonctions spécifiques à l'interface utilisateur. Si je devais réécrire l'intégralité de votre interface utilisateur en remplaçant toutes les vues, je pourrais finir par combiner la vue "EditPreferences" avec une autre vue, et je ne veux donc jamais l'ouvrir dans un autre écran. Si cela était lié au ViewModel, il serait difficile de se déplacer. Dans cette situation particulière, j'aurais un bouton ou un élément de menu dans mon "ShellView" qui crée une nouvelle instance de ma vue "EditPreferences", puis passe dans le ViewModel "EditPreferences" qui peut provenir d'une propriété dans mon "ShellViewModel" ", ou peut-être ma vue" EditPreferences "instancie le ViewModel lui-même.

Voici une question similaire sur le SO qui dit essentiellement la même chose: M-V-VM Design Question. Calling View from ViewModel

1

Demandez l'PreferencesDialog implémenter une interface qui est l'une des propriétés de la commande EditPreference. La commande interagirait avec le dialogue via l'interface. Pour le test unitaire, l'objet mock implémenterait l'interface à la place.

La classe de dialogue peut alors résider sur votre couche supérieure.

+1

Je pensais que l'un des buts de MVVM était de ne pas avoir de ViewModel au courant de la vue (ou dialogue dans votre exemple)? Ainsi, n'importe quel nombre de vues (ou aucune) peut utiliser un ViewModel à tout moment. Avoir votre ViewModel définir des choses sur une interface de vue brise un peu cela. –

+0

Ce n'est pas parce que l'interface isole la commande de l'implémentation du dialogue. –

+0

C'est le modèle MVP. La modification de l'interface View proposée entraînerait la rupture du ViewModel, par ex. changer la signature d'une méthode ou d'un type de propriété, BAM vous venez de casser votre ViewModel qui a une dépendance sur l'interface. Dans MVVM, la vue "observe" le ViewModel via des liaisons. Apporter des modifications à la vue (par exemple ajouter des contrôles) ne nécessitera pas de changer d'interface ou même de recompiler le ViewModel. Chose cool, un seul ViewModel peut être «observé» par de nombreuses vues. Voir le modèle d'observateur dans le livre de GOF et lisez la section de documents de prisme «modèle de présentation» si vous êtes plus intéressé par ceci :) –

0

Mes 2 cents est:

  1. passer quelque type de contrat viewfactory comme paramètre de commande ou un contrat injectent viewfactory dans le modèle de vue.Le modèle de vue utilisera viewfactory pour créer les vues modales/non modales dont il a besoin. La viewfactory pourrait aussi prendre en paramètre de sa méthode Show/ShowModal un viewmodel à afficher. En outre, viewfactory pourrait utiliser un datatemplate pour afficher n'importe quel viewmodal passé en paramètre. Ajoutez une propriété ShowViewModel au viewmodel en question. Un DataTrigger pourrait alors surveiller cette propriété et quand il est d'un type particulier montrer la vue, etc.

Questions connexes