Vielleicht habe ich Flex-Entwicklung mit Frameworks wie Cairngorm zu lange gemacht, aber MVVM bekomme ich immer noch nicht. Ich bin mir bewusst, dass Cairngorm ein Framework ist und MVVM ein Designmuster ist, aber was ich hier vergleiche, sind Cairngorms-Implementierungen von Designmustern, hauptsächlich der Model-View-Controller und das Befehlsmuster. Versteht mich nicht falsch, ich denke, die Idee, eine Ansicht an ein Ansichtsmodell zu binden, ist großartig und die Vorteile in der Testbarkeit und im Designer-Programmierer-Workflow sind groß. Aber es gibt zwei Dinge, die mich stören: Zum einen programmiere ich alle meine Aktionen mit Befehlen, die mich übrigens auch von Cairngorm abgrenzten. Nur in Cairngorm bot die Art, wie sie das Befehlsmuster implementierten, den Vorteil, einen zentralisierten Controller für all Ihre Befehle zu haben, den Sie mit MVVM nicht zu bekommen scheinen, es sei denn, ich verpasse etwas. Und wenn ich dachte, dass die Implementierung der Befehle in Cairngorm in MVVM verschachtelt ist, ist es am schlimmsten, ich meine, private Klassen erstellen zu müssen, die ICommand für alles, was ich tue, implementieren, scheinen zu viel zu sein. Und dann hast du das Problem, dass nicht alle Steuerelemente Befehle implementieren, also zum Beispiel, wenn du eine ListBox benutzt, die ich oft benutze, hast du kein Glück; Es gibt Workarounds, aber alle Arten von Convolut.
Die andere Sache, die mich stört, ist die Kommunikation zwischen den View-Modellen. In einem Standard-Model-View-Controller sammeln Sie alle Informationen zu einem zentralisierten Modell, das von den Views beobachtet wird, aber das scheint bei MVVM nicht der Fall zu sein, zumindest nicht in den Beispielen, die ich gesehen habe. Wenn Sie zum Beispiel ein Steuerelement mit einer Liste haben, mit der Sie ein Element auswählen, das dann als Quelle für verschiedene Sichten und Folgeaktionen verwendet wird, ist mir nicht klar, wie Sie alle Änderungen ohne ein zentralisiertes Modell benachrichtigen.
Ich kenne MVVMFoundation und die Arbeit von Tom Ershamam über WPF Commands Everywhere. Nannte mich altmodisch, aber ich denke, dass, um ein Muster wirklich zu verstehen, Sie eine Anwendung bauen müssen, die es von Grund auf verwendet. Was ich tue, aber die ganze Zeit über denke ich, dass ich etwas Wesentliches vermissen muss, weil ich nicht in der Lage bin, diese kleine Stimme in meinem Kopf zu beruhigen, die mir immer wieder sagt, dass es einen besseren Weg geben muss.
Unabhängig vom Framework / Architektur / Muster benötigen Sie immer etwas, das auf einen Klick auf eine Schaltfläche, auf eine Symbolleiste / ein Menü oder auf ein einfaches Formular reagiert. Und Sie brauchen etwas, das sagt, wenn die Schaltfläche / Menü aktiviert werden soll. Daher ist die ICommand-Schnittstelle dafür geeignet. Ich stimme Petoj zu, du brauchst keine neue Klasse. Ich habe eine einfache Implementierung geschrieben, die 1 oder 2 Delegaten benötigt, eine für die eigentliche Antwort auf den Klick (die Methode Execute) und eine optionale für den Status "enabled" des Befehls. Auf diese Weise ist das ViewModel nicht überladen.
Aber ich stimme zu, dass dies keine zentrale Sammlung von Befehlen ist. Aber willst du wirklich eins? Ich bevorzuge es, Befehle, die für einen Teil einer App spezifisch sind, in das entsprechende Ansichtsmodell aufzunehmen, wobei entsprechende Ereignisse ausgelöst werden, wenn der Rest der App benachrichtigt werden sollte.
Für die Listbox binde ich die SelectedItem-Eigenschaft an eine Eigenschaft im ViewModel. Mit INotifyPropertyChanged kann jeder Teil Ihres Codes auf die Änderung reagieren.
Die Kommunikation zwischen ViewModels ist eine gute Frage. Wenn Sie unterschiedliche Ansichten auf demselben Bildschirm benötigen, können Sie ein "Super" -Sichtmodell verwenden, das das Ansichtsmodell jeder Ansicht enthält. Es gibt einige MVVM-Frameworks da draußen. Ich habe Teile von Mark Smiths MVVM-Helfern verwendet, was ziemlich leicht und nützlich ist.
Nun, ich schreibe einen neuen Befehl, der ICommand implements scheint ein wenig über den Töten zu sein: VB.NET: Öffentliche Klasse RelayCommand Implementiert ICommand
%Vor%C #
%Vor%und um es zu verwenden, geben Sie einfach eine Eigenschaft vom Typ ICommand frei, die einen neuen RelayCommand mit Delegaten an eine Funktion ...
zurückgibtvb.net
%Vor%C #
%Vor%Helo Julio,
Sieh an, als wäre das ein alter Post, aber ich liebe deine Frage wirklich.
Vor kurzem bin ich ein flexibler Programmierer und ein WPF auch. Ich kannte Cairngorm (lässt Say [C]) Framework gut, habe gelernt, Präsentationsmodell zu verwenden mit Parsley Framework, und in WPF merke ich, dass Presentation Model in MVVM Muster geändert wurde.
Befehl
Befehl in [C] ist anders als in MVVM, Befehl in [C] ist als Befehlsmuster zufriedener , wo in [C] Controller als Invoker fungieren, also in [C] den Befehl Tatsächlich kann Chain, Rückgängig, Transaction usw. unterstützt werden. In MVVM Command ist weit von Command-Muster. Die wichtigste Idee bei der Verwendung von Command in MVVM, da ICommand die einzige Möglichkeit ist, eine Bindung mit der Operation durchzuführen. In Flex binden Sie die Methode einfach an das Ereignis mit click="{viewmodel.doOperation()}"
, aber nicht an WPF.
Modellsuche
Es ist eine schlechte Übung, Ihren Anwendungsstatus auf einem einzelnen Modell-Locator zu zentralisieren, wie es [C] getan hat. Auf der anderen Seite werden Sie die Chance verlieren, Ihren Code "leicht" zu testen, wenn Sie das tun. Je abhängiger Ihr Code ist, desto schwieriger ist es zu testen, wenn Ihr Model-Locator Tonnen kleinerer Modelle enthält, als Sie bereits eine große Menge an Abhängigkeit von Ihrem Code haben. UND, die gruseligste Sache mit Singleton ist es unmöglich zu verspotten. Wenn Ihr Modell-Lokalisierer also nicht prüfgerätefreundlich ist, kann Ihr Geräte-Testprozess schmerzhaft sein.
Tatsächlich wird keine Best Practice im MVVM-Kontext für das gemeinsame Modell zwischen Ansichten verwendet, wie Sie es nennen, aber Sie sollten sich die Abhängigkeitsinjektion Begriff, um das zu erreichen.
Beste Grüße
Ok, um diesem Thread eine Art Schluss für zukünftige Referenz zu geben. Zuerst vielen Dank für die Antworten. Der RelayCommand ist wirklich eine gute Idee; Es rationalisiert die Dinge sehr und macht das Testen und die Arbeit damit einfach. Sieht so aus, als ob es der richtige Weg ist. Die Bindung an das SelectedItem scheint auch das Problem bezüglich fehlender Befehlsunterstützung in ItemsControl zu lösen. In Bezug auf die Kommunikation zwischen ViewModels bin ich nicht davon überzeugt, dass ein Super View-Modell mein Problem löst, da es das Modell an meinen visuellen Baum bindet. Außerdem habe ich in dieser Struktur keinen Weg gefunden, um eine saubere, objektunabhängige Kommunikation zwischen allen Ansichtsmodellen in verschiedenen Hierarchien zu ermöglichen. Also versuche ich zuerst ein zentralisiertes Modell zu erstellen, das ein Singleton ist, der die INotifyPropertyChanged-Schnittstelle implementiert. Die ViewModels können dann eine Instanz dieses Modells haben und darauf agieren, indem sie die entsprechenden Eigenschaftenänderungen mit unserem guten alten Freund, dem Observer-Muster, propagieren. Scheint gut zu funktionieren, obwohl ich ein wenig Angst vor zirkulären Referenzen habe. Was denkst du?
Menschen, die sich über MVVM unterhalten, haben es zu theoretisch erscheinen lassen und Flex hat wirklich eine völlig andere Architektur, was MVVM für Leute, die aus Flex kommen, etwas komplizierter macht.
Lassen Sie mich Ihnen ein sehr einfaches Beispiel geben,
In Flex erstellen wir meistens eine MXML für die UI-Komponente, und wir haben unser bindbares Modell und schreiben unseren Code hauptsächlich in die Ereignisse von UI-Komponenten und nicht-UI-Komponenten. Zum Beispiel, WebService, HttpService etc, sie sind keine UI-Komponente, aber sie können immer noch innerhalb der MXML sein und sie können leicht innerhalb des MXML-Codes zugegriffen werden.
Grundsätzlich können Sie also Model + View + Controller in einer MXML-Datei sehr leicht organisieren.
In Silverlight können Sie in XAML nur UI-Elemente als untergeordnete Elemente der Seiten- / Benutzersteuerung haben, die Sie bearbeiten. Es gibt Einschränkungen, XAML lässt Sie Ihr Nicht-UI-Element nur in Ressourcen platzieren, und getypte Variable der hinzugefügten Ressource ist im Code hinter XAML nicht leicht zugänglich. Sie müssen die Suchressource aufrufen, um auf den Code zuzugreifen.
Um Ihnen die Arbeit zu erleichtern, zwingt Sie MVVM, verschiedene Dateien zu definieren.
Sie haben eine Datei, das ist Ihr Modell selbst, zum Beispiel Customer.cs
Sie haben eine andere Datei, das ist Ihr ViewModel, was im Grunde die Kombination von Model + Commands ist. Und Sie schreiben Ihren Controller-Code in Executed-Ereignis des Befehls.
Sie haben eine andere Datei, das heißt, Ihre Ansicht, Ansicht bindet grundsätzlich an alle Eigenschaften von ViewModel, die entweder Model oder Commands sind.
Tags und Links wpf mvvm design-patterns