2008-11-24 11 views
7

Ich bin MVP/M-V-VM in WPF implementieren und ich habe viel Glück damit. Ich sehe jedoch nicht, wie dieses Modell die Implementierung von Modal-Dialogfeldern unterstützt. Ich habe meine Arbeit von Crack.NET (http://www.codeplex.com/cracknetproject) abgeleitet, um zu lernen, wie dieses Zeug funktioniert.Model-View-Presenter und Modal Dialogfelder .... Wie?

Ich habe eine ShellView-Ansicht (die nur XAML ist), die ein Menü enthält. Das Menü bindet an einen Befehl in der ShellModelView, der "EditPreferences" sagt.

Die ShellModelView implementiert den ICommand für EditPreferences und hier möchten wir ein Dialogfeld erstellen, damit der Benutzer Einstellungen für die Anwendung bearbeiten kann.

Mehrere Probleme hier: 1. Die ShellModelView hat keine Referenz auf die ShellView, um den Dialog ordnungsgemäß Eltern. Die ShellModelView ist der DataContext der ShellView, aber ich sehe keine Backreference, die eingerichtet ist. 2. Die ShellModelView sollte sowieso keine explizite UI laden. Was ist das richtige Interaktionsmodell hier? 3. Wie baue ich meinen PreferencesDialog so auf, dass er zwischen Logik und Ansicht getrennt ist? PreferencesDialog selbst muss ein Fenster sein, damit Sie ShowDialog darauf aufrufen können, aber das bedeutet, dass Sie einen Verweis auf das Fenster (z. B. Ansicht) benötigen, um es zu instanziieren. Idealerweise sollte ich in der Lage sein, den Code/die Validierung in PreferencesDialog zu testen, ohne die Ansicht zu instanziieren (vielleicht mit einer Mock-Ansicht?).

Antwort

1

In Ihrem Fall benötigen Sie einen Controller. Der Controller sollte verantwortlich sein, um das Einstellungsdialogfenster anzuzeigen.

Wie ich es mir vorstellen kann, sollte der Controller für das Erstellen des DataContext der ShellModelView und der Bindungsansicht verantwortlich sein. Der Controller sollte auch für die Befehlsausführung von EditPreferences zuständig sein. In der Ausführungslogik erstellt der Controller einen neuen PreferencesDialog und das entsprechende View-Modell.

Sie können ähnliche Muster in Prism finden, wenn Sie es nicht bereits getan haben. Sie können den DelegateCommand, der dort zur Verfügung gestellt wird, auch wiederverwenden :)

6

Vielleicht ist dies nicht der geeignete Weg, um es zu betrachten, aber das ist der Ansatz, den ich mit M-V-VM in WPF nehme. Öffnen von Fenstern und Dialogfeldern oder eine "EditPreferences" -Ansicht sind UI-spezifische Funktionen. Wenn ich die gesamte Benutzeroberfläche neu schreiben würde und alle Ansichten ersetzen würde, könnte es passieren, dass ich die Ansicht "EditPreferences" mit einer anderen Ansicht kombiniere und sie deshalb nie auf einem anderen Bildschirm öffnen möchte. Wenn dies mit dem ViewModel verbunden wäre, wäre es schwierig, sich zu bewegen. In dieser speziellen Situation hätte ich eine Schaltfläche oder einen Menüeintrag in meiner "ShellView", die eine neue Instanz meiner "EditPreferences" -Ansicht erstellt und dann das ViewModel "EditPreferences" übergibt, das entweder von einer Eigenschaft in meinem "ShellViewModel" stammt "oder meine" EditPreferences "-Ansicht instanziiert das ViewModel selbst.

Hier ist eine ähnliche Frage auf SO im Grunde, dass sagt dasselbe: M-V-VM Design Question. Calling View from ViewModel

1

Haben die Einstellungen eine Schnittstelle implementieren, die eine der Eigenschaften des EditPreference Befehl ist. Der Befehl würde mit dem Dialog über die Schnittstelle interagieren. Für Unit-Tests würde das Mock-Objekt stattdessen die Schnittstelle implementieren.

Die Dialogklasse kann sich dann auf Ihrer höchsten Ebene befinden.

+1

Ich dachte, eines der Ziele von MVVM ist nicht zu erreichen, die weiß, dass das Ansichtsmodell eine Sache, über die Aussicht (oder Dialog in Ihrem Beispiel)? Damit eine beliebige Anzahl von Views (oder keine) ein ViewModel zu einem beliebigen Zeitpunkt verwenden kann. Wenn Sie Ihr ViewModel Dinge auf einer View-Oberfläche einstellen, wird das irgendwie kaputt gemacht. –

+0

Es nicht, weil die Schnittstelle den Befehl von der Implementierung des Dialogs isoliert. –

+0

Das ist MVP-Muster. Das Ändern der vorgeschlagenen View-Oberfläche würde das ViewModel, z. Ändern Sie die Signatur einer Methode oder eines Typs einer Eigenschaft, BAM haben Sie gerade Ihr ViewModel, das eine Abhängigkeit von der Schnittstelle hat. In MVVM beobachtet die Ansicht das ViewModel über Bindungen. Änderungen an der Ansicht (z. B. das Hinzufügen von Steuerelementen) erfordern keine Änderung der Schnittstellen oder Neukompilierung des ViewModel. Cool ist, ein einzelnes ViewModel kann von vielen Views "beobachtet" werden. Siehe Observer-Muster in GOF-Buch und lesen Sie Prism-Dokumentation Abschnitt "Presentation Model", wenn Sie mehr daran interessiert sind :) –

0

Meine 2 Cent:

  1. Pass eine Art viewfactory Vertrag als Befehlsparameter oder einen viewfactory Vertrag in das Ansichtsmodell injizieren.Das Ansichtsmodell verwendet die viewfactory, um beliebige modale/nicht-modale Ansichten zu erstellen. Die viewfactory könnte auch als Parameter ihrer Show/ShowModal-Methode ein Viewmodel zur Anzeige bringen. Darüber hinaus könnte die Viewfactory eine Datamaplatte verwenden, um ein beliebiges als Parameter übergebenes Viewmodal anzuzeigen.

  2. Fügen Sie dem fraglichen Ansichtsmodell eine ShowViewModel-Eigenschaft hinzu. Ein Datatrigger könnte dann für dieses Objekt beobachten und, wenn es von einem bestimmten Typ ist die Ansicht, zeigt etc.