MVVM Light Toolkit - Relaycommands, Delegatecommands und ObservableObjects
-
15-10-2019 - |
Frage
Ich habe gerade angefangen, mit Laurent Bugnion zu experimentieren MVVM Light Toolkit. Ich denke, es wird es mir wirklich gefallen, aber ich habe ein paar Fragen.
Bevor ich zu ihnen komme, lassen Sie mich erklären, woher ich komme. Ich verwende derzeit eine Kombination von Josh Smiths MVVM Foundation und ein weiteres Projekt auf Codeplex namens MVVM Toolkit. ich benutze ObservableObject
und Messenger
von der MVVM Foundation und DelegateCommand
und CommandReference
vom MVVM -Toolkit.
Die einzige wirkliche Überlappung zwischen der MVVM Foundation und MVVM hat es eingenommen, dass beide eine Implementierung für ICommand
: MVVM Foundation hat RelayCommand
und MVVM hat hat hat DelegateCommand
. Von diesen beiden, DelegateCommand
scheint anspruchsvoller zu sein. Es beschäftigt a CommandManagerHelper
Das verwendet schwache Verweise, um Speicherlecks zu vermeiden.
Nachdem dies gesagt ist, hier sind meine Fragen:
Warum verwendet MVVM -Licht
RelayCommand
stattDelegateCommand
? Ist die Verwendung schwacher Referenzen in einemICommand
Unnötig oder nicht aus irgendeinem Grund empfohlen?Warum gibt es keine
ObservableObject
In MVVM -Licht?ObservableObject
ist im Grunde nur der Teil vonViewModelBase
das implementiertINotifyPropertyChanged
, Aber es ist sehr bequem als separate Klasse, da Ansichtsmodelle nicht die einzigen Objekte sind, die implementiert werden müssenINotifyPropertyChanged
. Nehmen wir zum Beispiel an, Sie haben ein Datagrid, das an eine Liste von bindetPerson
Objekte. Wenn eines der Eigenschaften inPerson
kann sich ändern, während der Benutzer das DataGrid anzeigt,Person
müsste implementierenINotifyPropertyChanged
. (Mir ist klar, dass wennPerson
wird mit so etwas wie linqtosql automatisch generiert, es wird wahrscheinlich bereits implementiertINotifyPropertyChanged
, Es gibt jedoch Fälle, in denen ich beispielsweise Ansichtspezifische Versionen von Entitätsmodellobjekten erstellen muss, da ich einen Befehl einfügen muss, um eine Schaltflächenspalte in einem Datenträger zu unterstützen.)
Vielen Dank.
Ps hier ist der Code für DelegateCommand
Aus dem MVVM -Toolkit:
https://docs.google.com/document/pub?id=1APCX5SBCFHI5FBHV8KI3ZA6J34SP2T80LQZDJ89V8CU
Lösung
Es sieht so aus, als ob das Problem, das durch die erste Frage aufgeworfen wurde, im neuesten Build gelöst wurde:
Entsprechend Die MVVM Light Toolkit Codeplex Site (unter "manuell anheben des Ereignisses Canexexecuteched"), die CommandManager
wurde insgesamt beseitigt.
Wie für Observable Object
, Ich habe hinzugefügt Ein Artikel zum Ausgaber -Tracker Auf der Codeplex -Site.
Andere Tipps
Sie können auch nachdenken Katel. Es unterstützt ein DataObject (sowohl generisch als auch nicht generisch), das genau das unterstützt, wonach Sie suchen (ein Objekt, das InotifyPropertychanged, idataErrorinfo und vieles mehr implementiert). Anschließend wird die ViewModelBase aus der sehr leistungsstarken DataObjectBase -Klasse abgeleitet, sodass Sie die DataObjectBase für Datenobjekte und die ViewModelBase für Ansichtsmodelle verwenden können.
Es speichert Sie auch vor dem Erstellen von Messenger, da Sie das Interessierungsattribut für ein Ansichtsmodell einfach verwenden können, um Änderungsbenachrichtigungen eines anderen Ansichtsmodells zu erhalten.
Ihre beiden Fragen schlagen mir nachdrücklich vor, dass Sie es vorziehen, etwas zu verwenden mehr als das View -Modellkonzept, um die Geschäftslogik zu definieren.
Das DelegateCommand
definiert a getrennt Klasse außer dem View -Modell. Das ObservableObject
ist eine Instanz von a getrennt Klasse außer dem View -Modell. Dies ist keine Regel, sondern persönliche Präferenz des Augenblicks: Das View -Modell reicht für mich als Container für die Geschäftslogik in Bezug auf Visuals aus. Dies kann meine Präferenz für MVVM-Licht verraten-was ich im Moment nicht fehlt.
Ich bin mir nicht ganz sicher, was im Datagrid -Beispiel vor sich geht. Was ich sagen kann ist, dass der Datagrid nicht sehr flexibel ist-in WPF, der DataGridTemplateColumn
Kann ein Ansichtsmodell deklarativ an eine Ansicht binden (z. B. eine Benutzersteuerung). Vielleicht macht das Sinn:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataView="{x:Type m:YourViewModelForButton}">
<v:YourViewWithButton/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>