2009-08-24 5 views
1

Ich dachte, ich hier in der Hoffnung, schreiben würde, dass vielleicht jemand mit MVVM Know-how der Lage wäre, Meinungen zu bieten, ob die folgende ist eine gute Idee:MVVM- und Stateful-Befehle - Gute oder schlechte Idee?

I Sacha Barbers Cinch MVVM Rahmen bin mit, die Marlon enthält Grechs SimpleCommand-Klasse.

Eine Sache, diese Klasse nicht dem hat einige andere Alternativen haben, ist eine Text-Eigenschaft, die häufig verwendet werden können UI-Elemente auf den ‚Titel‘ des Befehls Betrieb zu binden. Folglich habe ich eine Erweiterung für diese Klasse geschrieben, die eine Text-Eigenschaft verfügbar macht.

Nun, was ich habe, ist, laufe in einem Anwendungsfall, wo ich einen Befehl bin mit Verbindung zu einem Gerät wechseln. Es gibt eine Reihe verschiedener Möglichkeiten, dies zu implementieren (nicht immer - es ist Software!). Eine Möglichkeit besteht darin, mehrere Befehlsobjekte aus meinem ViewModel bereitzustellen - eine für "Trennen" und eine für "Verbinden". Lassen Sie das Ansichtsmodell eine Eigenschaft verfügbar machen, die den Verbindungsstatus (IsConnected) angibt und die Ansicht bedingt an den Befehl Verbinden oder Trennen gebunden wird. Meine Reaktion auf diese Option ist jedoch ... yuck!

Woran ich anfänglich zu suchen begann, war nicht nur das Bereitstellen einer Text-Eigenschaft, sondern auch das Implementieren des Befehlsobjekts INotifyPropertyChanged, so dass die Texteigenschaft je nach Systemzustand vom Viewmodel dynamisch in 'Verbinden' oder 'Trennen' geändert werden kann . Dadurch kann ich vermeiden, mehrere Befehle zu haben und nur ein einziges 'ToggleConnection' Befehlsobjekt verfügbar zu machen.

diesen Weg allerdings Ab nach unten, kommt mir der Gedanke, dass es andere Variationen dieses Musters sein kann, wobei die Benutzeroberfläche geändert werden muss nach Befehlszustand. Beispielsweise können Sie den Text des Befehls nicht nur entsprechend dem Verbindungsstatus ändern, sondern möglicherweise auch an Stellen, an denen sich ein Symbol entsprechend dem Verbindungsstatus ändern muss. Also begann ich eine "Stateful" -Klasse zu schreiben, die INotifyPropertyChanged implementiert und zwei Eigenschaften - "Text" und "State" - freilegt. Ich habe die Klasse generisch gemacht, so dass der Typ des Zustands vom Benutzer definiert werden kann (ich bevorzuge es normalerweise, "Objekt" nicht zu verwenden, wo vermeidbar).

Die Frage, die ich habe, ist ... Denken Sie, das ist eine gute oder schlechte Idee? Es kann von der ursprünglichen Absicht/Gestaltung der Befehle abweichen; Nach dem, was ich gesehen habe, könnte es im Allgemeinen der Fall sein, dass Befehlsobjekte staatenlos sein sollten, da sie die "Verben" des Systems sind. Bei gerouteten Befehlen würde normalerweise nur das Ziel des Befehls einen Zustand haben, wenn ich die Dinge richtig verstehe. Insbesondere da derselbe Befehl an verschiedene Handler weitergeleitet werden kann, abhängig davon, wo Befehlsbindungen deklariert sind.

Also, ich denke, dass zumindest mit gerouteten Befehlen, Zustand keinen Sinn ergeben würde.

Aber ich bin nicht mit gerouteten Befehle zu tun - ich speziell mit MVVM Befehle zu tun habe. In diesem Fall gibt es im Grunde genommen kein bedingtes Routing von Befehlen - die MVVM-Ansichten binden direkt an die Befehlsobjekte eines bestimmten Ansichtsmodells und es sind Execute- und Canexecute-Handler.

In diesem Fall macht es Sinn?

Ich habe eine Kopie des Codes in Frage angebracht, falls es von Nutzen/Interesse ist.

Danke, Phil

Antwort

1

Es ist wirklich an Ihnen, was denken Sie, wäre einfacher, mit zu arbeiten.

Ich persönlich legte die .Text Eigenschaft nicht auf meine Befehle, nur weil ich aus diesen Befehlen keine Wiederverwendung erhalten.Anders verhält es sich mit den RoutedUIC-Befehlen, die im Framework bereitgestellt werden (oder ähnlichen benutzerdefinierten statischen Befehlen), da sie überall wiederverwendet werden und sich die Übersetzung von "Exit" bei diesem Befehl ändern würde, würde sie sich in der gesamten Anwendung widerspiegeln. Dies ist in Ihrem Beispiel nicht der Fall - alles wäre einmalig.

In Ihrem Fall ist dieser Text Ihres Schaltflächentextes wirklich von Ihrem Befehl entkoppelt (obwohl einer den anderen beeinflusst) und so wird es wahrscheinlich einfacher und ein wenig weniger Code, um sie zu entkoppeln, aber der Unterschied isn Das wird so viel sein und es wird mehr als alles andere eine Sache des Geschmacks sein.

Ich bin definitiv mit dir auf der 2 Befehle Sache - blech. Die meisten Tastendelegierten, die Sie schreiben, müssen auf den Zustand reagieren (der Dienst, mit dem Sie sprechen, ist nicht erreichbar, diese Daten müssen auf diese Weise ausgefüllt werden, wenn der Benutzer dies ausgewählt hat usw.), also glaube ich nicht, dass es falsch ist Der Delegierte passt sich an Stateful Information auf dem ViewModel an.

Wie auch immer, das ist ein bisschen wortreich ... das Mitnehmen ist "tun, was auch immer sich wohl fühlt".

+0

Dank Anderson, gute Kommentare. Ich vermute, dass mein Unbehagen von der vorherigen Verwendung von gerouteten Befehlen herrührt, aber dann ist das gesamte Verhalten von MVVM-Befehlen anders. Ich bevorzuge den Befehlstext an einer Stelle mit dem Befehl, da ich normalerweise mehrere UI-Elemente gebunden habe. Ich denke, das Viewmodel, das die Lokalisierung durchführt, mag ein bisschen funky wirken, aber dann ist es offensichtlich eng mit der Bereitstellung einer UI-Ansicht verbunden. Ich kann auch einige Vorteile sehen, wenn ich UI dynamisch erzeuge - z. Binden an eine Liste von Befehlen mit einem Style/Datameplate, das den Text des Befehlsobjekts erstellt. Prost! – Phil

+0

In diesem speziellen Fall gewinnen Sie immer noch nichts. Es ist mir klar, dass Sie mehrere Schaltflächen an den gleichen Befehl für die Eigenschaft .Text binden, aber wie unterscheidet sich das von der Bindung an eine andere Eigenschaft in Ihrer ViewModel-Eigenschaft "ConnectionText" oder einer ähnlichen Eigenschaft. Ich möchte nur, dass Sie darüber nachdenken ... Sie sprechen hier über Symantec ... Sie sind im Wesentlichen dasselbe in Ihren Nutzungsszenarien. –

+0

Ich bekomme, was Sie Anderson sagen, und erwägen, eine ConnectionText-Eigenschaft zu haben, wie Sie beschreiben. Was ich vor, obwohl getan gesehen haben, und gern mit Befehlen die Verwendung von relativen Bindungen in Verbindung, zB: content = "{Binding Relative = {Relativeselbst}, Path = Command.Description}" I so aus einer Reihe von Gründen - 1. es reduziert die Anzahl der Stellen, an denen die Eigentumsverweise angegeben werden müssen; Wenn wir nur den Text oder "Titel" sprechen, der für eine Schaltfläche angezeigt wird, würde die Reduzierung von 2 (die Befehls- und Texteigenschaften des MVVM) zu 1. – Phil

0

Wie das letzte Plakat sagte: "Was auch immer sich wohl fühlt."

In meinem Fall verwende ich normalerweise etwas wie die DelegateCommand. Wenn ich an einige Daten binden muss, binde ich an die VM. Wenn der Befehl ausgeführt wird, wird er in meiner VM ausgeführt (über den Delegate, der dem DelegateCommand bei init bereitgestellt wird). Dann darf/darf der ausgeführte Delegat keinen wiederverwendbaren Code ausführen, um den Befehl zu erfüllen.

Es klingt, als ob Sie den Befehl als eigene VM verwenden möchten. Ich habe nie daran gedacht, das vor mir selbst zu tun, aber wenn es dir gut tut, tu es! :)

+0

Ich denke, das ist ein guter Weg, es auszudrücken - der Befehl wird zu einer Mini-VM! Prost :) – Phil