2009-06-21 3 views
6

Ich mag die MVVM-Idee von RelayCommand, die durch das ViewModel ausgesetzt ist. Das ist nett und elegant für Operationen, die ohne weitere Benutzereingaben durchgeführt werden können. Einfach. Testbar.MVVM und Befehle, die mehr GUI zeigen

Allerdings sind nicht alle Operationen UI-less. Einige erfordern eine Bestätigung ("Möchten Sie wirklich löschen?"). Andere erfordern noch mehr Informationen. Das Öffnen einer Datei kann von einem Dialogfeld "Datei öffnen" bis hin zu einem vollständigen Importassistenten führen.

Was ist der beste Weg, innerhalb einer MVVM-Anwendung Befehle zu schreiben, die Benutzereingaben erfordern? Gibt es ein etabliertes Muster, um dies irgendwie mit der Abhängigkeitsinjektion zu lösen? Soll ich einen KeyDown-Handler im Code-Behind schreiben und das Event explizit ausführen lassen? Sollte ich auf RoutedUICommand zurückgreifen und alle "Zeige den nächsten GUI" -Code in meine Ansicht einfügen? Oder ist etwas offensichtlich, das ich völlig vermisse?

Antwort

4

Normalerweise verwende ich Dependency Injection, um eine Art abstrakte IShowTheInterface-Sache zu injizieren, und dann Methoden auf die Abstraktion aus dem Command aufrufen. Diese Methoden sollten Ihnen dann die Antworten geben, die Sie benötigen, um zu bestimmen, ob die Aktion überhaupt fortgesetzt werden soll und welche Eingaben der Benutzer gegeben hat.

Ich habe dies kürzlich als Beispiel in einem blog post with a bit of a different topic verwendet.

1

Diese Art von Zeug (Bestätigungsdialoge, Datei öffnen Dialoge usw.) werden normalerweise zwischen Anwendungen geteilt. Also meine Präferenz ist sie nicht in das ViewModel gesetzt.

ViewModel ist App-spezifisch und es ist keine gute Idee, ViewModelBase auf unbestimmte Zeit zu erweitern. Erstellen Sie stattdessen wiederverwendbare Verhaltensweisen, um die Ansicht zu erweitern. Es gibt quete einige Verhalten Proben am Expression Blend Gallery

EDIT:

Behaviors können Eigenschaften haben und Sie diese Eigenschaften verwenden können, nicht nur Verhaltensmerkmale angeben, sondern auch ein Feedback zu bekommen:

<Button Content="Open Document"> 
    <i:Interaction.Behaviors> 
     <local:FileOpenBehavior 
      FileNameTarget="{Binding ElementName=tbDocName}"/> 
    </i:Interaction.Behaviors> 
</Button> 

Im obigen Beispiel kann tbDocName ausgeblendet werden - oder Sie können eine Bindung an eine Eigenschaft Ihres ModelViews herstellen.

+0

Der Teil "show a Open dialog" kann wiederverwendbar sein; Aber dann müssen Sie etwas mit dieser Datei machen, und das wird anwendungsspezifisch sein, also bin ich mir nicht sicher, ob ich sehe, wie das funktioniert. Können Sie ein Beispiel dafür geben, wie Sie dies mit Verhaltensweisen tun würden? –

+0

@ joe-white Senden Sie eine Nachricht an den UI-Stack, die erfasst und an ein ViewModel weitergeleitet wird ... Oder wenn Sie eine Bindung an eine Property in einem ViewModel herstellen, wissen Sie, dass die Datei zugewiesen wird, wenn sich die Eigenschaft ändert. –