Ich habe eine MVVM-Anwendung. In einem der ViewModels befindet sich der 'FindFilesCommand', der eine ObservableCollection füllt. Ich implementiere dann einen 'RemoveFilesCommand' im selben ViewModel. Dieser Befehl öffnet ein Fenster, um mehr Benutzereingaben zu erhalten.
Wo / was ist der beste Weg, dies zu tun und gleichzeitig das MVVM-Paradigma einzuhalten? Irgendwie tun:
%Vor%im ViewModel scheint falsch zu sein.
Prost,
Steve
Ich betrachte dieses Szenario persönlich als eines, bei dem das Hauptfensteransichtsmodell eine Aufgabe für den Endbenutzer auftauchen soll.
Es sollte dafür verantwortlich sein, die Aufgabe zu erstellen und sie zu initialisieren. Die Ansicht sollte für das Erstellen und Anzeigen des untergeordneten Fensters verantwortlich sein und die Aufgabe als Ansichtsmodell des neu instanziierten Fensters verwenden.
Die Aufgabe kann abgebrochen oder festgeschrieben werden. Es wird eine Benachrichtigung ausgelöst, wenn es abgeschlossen ist.
Das Fenster verwendet die Benachrichtigung, um sich selbst zu schließen. Das übergeordnete Anzeigemodell verwendet die Benachrichtigung, um zusätzliche Arbeit zu leisten, sobald die Aufgabe festgeschrieben wurde, wenn Nacharbeit geleistet wird.
Ich glaube, dass dies der natürlichen / intuitiven Sache, die Menschen mit ihrem Code-Behind-Ansatz tun, so nahekommt, dass die UI-unabhängigen Probleme in ein View-Modell aufgespalten werden, ohne zusätzlichen konzeptionellen Overhead wie Services etc. einzuführen. p>
Ich habe eine Implementierung für Silverlight. Siehe Ссылка für weitere Details ... Ich würde gerne Kommentare / weitere Vorschläge dazu hören .
Im Realty-Beispiel von Jaime Rodriguez und Karl Shifflet von Reedridge erstellen sie das Fenster im Ansichtsmodell, genauer gesagt im Ausführungsteil eines gebundenen Befehls:
%Vor%Hier ist der Link: Ссылка
Ich denke, das ist kein großes Problem. Schließlich fungiert das Viewmodel als "Bindeglied" zwischen der Ansicht und der Business-Schicht / Datenschicht, so dass es normal ist, an die View (UI) gekoppelt zu werden ...
Onyx ( Ссылка ) wird dafür eine ziemlich gute Lösung bieten. Betrachten Sie als Beispiel den ICommonDialogProvider-Dienst, der von einem ViewModel wie folgt verwendet werden kann:
%Vor%Dies ist der Verwendung des konkreten OpenFileDialog sehr ähnlich, ist jedoch vollständig überprüfbar. Die Menge an Entkopplung, die Sie wirklich benötigen, wäre ein Implementierungsdetail für Sie. In Ihrem Fall möchten Sie vielleicht einen Service, der die Tatsache, dass Sie einen Dialog verwenden, völlig verbirgt. Etwas in der Art von:
%Vor%Sie müssen dann sicherstellen, dass die View über eine Implementierung für den IRemoveFiles-Service verfügt, für die Ihnen mehrere Optionen zur Verfügung stehen.
Onyx ist noch nicht fertig für die Veröffentlichung, aber der Code ist voll funktionsfähig und zumindest als Referenzpunkt verwendbar. Ich hoffe, die V1-Schnittstelle in Kürze zu stabilisieren und wird veröffentlicht, sobald wir eine anständige Dokumentation und Proben haben.
Ich habe dieses Problem auch mit MVVM bekommen. Mein erster Gedanke ist, einen Weg zu finden, den Dialog nicht zu benutzen. Mit WPF ist es viel einfacher, etwas einfacher zu machen als mit einem Dialog.
Wenn dies nicht möglich ist, scheint es am besten zu sein, wenn das ViewModel eine Shared-Klasse aufruft, um die Informationen vom Benutzer zu erhalten. Das ViewModel sollte sich nicht bewusst sein, dass ein Dialog angezeigt wird.
Als ein einfaches Beispiel könnte das ViewModel beispielsweise DialogHelper.ConfirmDeletion () aufrufen, wenn Sie den Benutzer zum Bestätigen eines Löschvorgangs benötigen. Dies würde einen Booleschen Wert dafür liefern, ob der Benutzer Ja oder Nein gesagt hat. Die eigentliche Anzeige des Dialogs würde in der Helper-Klasse erfolgen.
Für komplexere Dialoge, die viele Daten zurückgeben, sollte die Hilfsmethode ein Objekt mit allen Informationen aus dem Dialog zurückgeben.
Ich stimme zu, dass es nicht die beste Anpassung an den Rest von MVVM ist, aber ich habe noch keine besseren Beispiele gefunden.
Ich muss sagen, Dienste sind der Weg dorthin.
Die Service-Schnittstelle bietet eine Möglichkeit zur Rückgabe der Daten. Dann kann die tatsächliche Implementierung dieses Dienstes einen Dialog oder was auch immer zeigen, um die in der Schnittstelle benötigten Informationen zu erhalten.
Damit Sie dies testen können, können Sie die Service-Schnittstelle in Ihren Tests verspotten, und das ViewModel ist nicht klüger. Soweit es das ViewModel betrifft, hat es einen Dienst um einige Informationen gebeten und es hat erhalten, was es benötigt.
Was wir tun, ist so etwas, was hier beschrieben wird: Ссылка
Das ViewModel hat eine Eigenschaft namens ConfirmDeletionViewModel. Sobald ich die Eigenschaft gesetzt habe, öffnet das Verhalten den Dialog (modal oder nicht) und verwendet das ConfirmDeletionViewModel. Außerdem gebe ich einen Delegierten weiter, der ausgeführt wird, wenn der Benutzer den Dialog schließen möchte. Dies ist im Grunde ein Delegat, das die ConfirmDeletionViewModel-Eigenschaft auf null setzt.
Für Dialoge dieser Art. Ich definiere es als eine geschachtelte Klasse des FindFilesCommand. Wenn der grundlegende Dialog zwischen vielen Befehlen verwendet wird, definiere ich ihn in einem Modul, das für diese Befehle zugänglich ist, und lasse den Befehl den Dialog entsprechend konfigurieren.
Die Befehlsobjekte reichen aus, um zu zeigen, wie der Dialog mit dem Rest der Software interagiert. In meiner eigenen Software befinden sich die Command-Objekte in ihren eigenen Bibliotheken, so dass der Dialog vom Rest des Systems verborgen ist.
Etwas, das schicker ist, ist meiner Meinung nach übertrieben. Darüber hinaus versuchen, es auf dem höchsten Niveau zu halten, oft mit dem Erstellen einer Vielzahl von zusätzlichen Schnittstellen und Registrierungsmethoden. Es ist eine Menge Codierung für wenig Gewinn.
Wie bei jedem Rahmen wird sklavische Hingabe Sie durch einige seltsame Gassen führen. Sie müssen beurteilen, ob es andere Techniken gibt, die verwendet werden, wenn Sie einen schlechten Code riechen. Meiner Meinung nach sollten Dialoge eng an den Befehl gebunden und definiert sein, der sie benutzt. Auf diese Weise kann ich fünf Jahre später zu diesem Abschnitt des Codes zurückkehren und alles sehen, womit der Befehl zu tun hat.Auch in den wenigen Fällen, in denen ein Dialog für mehrere Befehle nützlich ist, definiere ich ihn in einem Modul, das allen gemeinsam ist. Aber in meiner Software ist vielleicht 1 von 20 Dialogen so. Die wichtigste Ausnahme ist der Dialog zum Öffnen / Speichern von Dateien. Wenn ein Dialog von Dutzenden von Befehlen verwendet wird, würde ich den vollständigen Weg zum Definieren einer Schnittstelle gehen, ein Formular erstellen, um diese Schnittstelle zu implementieren und dieses Formular zu registrieren.
Wenn Lokalisierung für die internationale Verwendung wichtig für Ihre Anwendung ist, müssen Sie sicherstellen, dass Sie dies mit diesem Schema berücksichtigen, da sich alle Formulare nicht in einem Modul befinden.
Tags und Links wpf mvvm design-patterns