2009-03-13 5 views
5

Es gibt viele gute Beispiele auf MVVM, aber ich bin immer noch verwirrt.Silverlight MVVM Modell und Ansichtsmodell verknüpfen

Nehmen wir an, Sie haben ein CustomerModel und ein CustomerViewModel. Es scheint, dass es eine Name-Eigenschaft im CustomerModel und eine im CustomerViewModel geben würde. Der Setter im CustomerViewModel legt die CustomerModel Name-Eigenschaft fest und ruft anschließend OnPropertyChanged (PropName) auf, damit die Benutzeroberfläche aktualisiert wird. Ist das wirklich richtig? Scheint wie die Getter/Setter werden zweimal definiert. Wenn Sie ein Modell mit 50 Eigenschaften haben, wird das wirklich langweilig.

Auch sagen wir, ich eine Qty-Eigenschaft festlegen. Das ViewModel aktualisiert das Modell. Das Modell aktualisiert seine Value-Eigenschaft basierend auf der neuen Menge. Wie wird das ViewModel benachrichtigt, dass sich die Model-Eigenschaft geändert hat?

Antwort

2

In dem von Ihnen angegebenen Kundenbeispiel enthält das CustomerModel alle Informationen, die von Ihrer Datenbank (oder einem anderen Backend) gespeichert werden. Das CustomerViewModel enthält ähnliche Informationen, wenn es auf der Benutzeroberfläche angezeigt wird (Name usw., möglicherweise 50 andere Eigenschaften, wenn Sie eine große Klasse haben), verwendet aber die INotifyPropertyChanged-Schnittstelle, um sie als Eigenschaften anzuzeigen, die die Ansicht (dh der XAML) kann zu binden.

z.B.

public int Name 
{ 
    get 
    { 
     return this.name; 
    } 

    set 
    { 
     if (this.name!= value) 
     { 
      this.name= value; 
      this.OnPropertyChanged("Name"); 
     } 
    } 
} 

Das Ansichtsmodell enthält auch andere Bits von UI-Zustand - Sichtbarkeit Flags, aktuellen Tab-Index, komplexere Bits von Texten aus Daten in verschiedenen Bereichen aufgebaut, ObservableCollection < > von Kinderartikeln, etc. Alle sind zu an den XAML gebunden sein.

Ich habe das ViewModel, das aus dem Modell erstellt wurde, als einen einmaligen, einseitigen Prozess, z. mit einem Konstruktor:

CustomerViewModel viewModel = new CustomerViewModel(customer); 

oder als Erweiterung Methode

CustomerViewModel viewModel = customer.ToViewModel(); 

Ich habe eine Bestimmung keine Ansichtsmodell für Änderungen an dem Modell für die Aktualisierung gesehen - den Punkt der Ansichtsmodell ist, dass es aus isoliert ist das Model. Es behält eine separate Kopie der Daten. Änderungen werden erst dann an das Modell weitergegeben, wenn Sie auf "Speichern" klicken. Wenn Sie stattdessen abbrechen, hat sich nichts im Modell geändert und es gibt nichts, was rückgängig gemacht werden kann.

Möglicherweise versuchen Sie zu sehr, das ViewModel mit dem Modell auf dem neuesten Stand zu halten. In den meisten Fällen wie Speichern oder Laden können Sie das aktuelle ViewModel einfach wegwerfen und aus dem aktuellen Status des Modells erstellen. Müssen Sie den UI-Status des ViewModels beibehalten und die darin enthaltenen Daten ändern? Es ist keine allgemeine Anforderung, aber es könnte mit einer oder zwei Methoden durchgeführt werden, die aufgerufen werden, wenn das Speichern oder Laden stattfindet.

Also gibt es auch die Annahme, dass diese Verdrahtung Logik irgendwo passiert. Deshalb beinhalten die meisten Muster, die Aufrufe betreffen, auch Controller, die verantwortlich sind, auf Befehle zu reagieren (z. B. einen Kunden anzeigen, einen Kunden speichern) und anschließend einen neuen UI-Status einrichten.

+0

Wenn Sie ViewModel getrennt vom Modell halten, wie werden Regeln im Modell angewendet? Angenommen, ich habe ein Modell mit Menge und Wert. Wenn ich die Menge auf dem ViewModel ändere, die zu dem Modell fließen sollte, das den Wert basierend auf der neuen Menge aktualisiert. Jetzt sollte das ViewModel den neuen Wert anzeigen. –

+0

"Wenn ich die Menge auf dem ViewModel ändere, das durch das Modell fließen soll" "Nein, nicht erst, wenn Sie auf die Schaltfläche Speichern oder Ähnliches drücken. Wenn Sie dies tun, sollte der Handler dafür das Modell aktualisieren, persistieren und ein neues ViewModel vom neuen Modellstatus absetzen. – Anthony

+0

Also, wenn es nicht zu dem Modell fließt, wie erhält das ViewModel dann jemals ein aktualisiertes Wertfeld? Wenn ich die Menge ändere, würde ich als Benutzer erwarten, den neuen Wert zu sehen. Der MV hat nicht die Geschäftslogik, um Wert zu berechnen, nur das Modell tut es. –

5

Ihr ViewModel muss das Model nicht strikt kapseln. In Ihrem Szenario hat das CustomerViewModel möglicherweise eine Customer-Eigenschaft, die am Ende bedeutet, dass Ihre Ansicht an die Model-Eigenschaften gebunden ist ... dies geschieht nur durch das ViewModel. Das ist vollkommen legitim. Allerdings gibt es oft einen Vorteil, dies zu kapseln. Ihr Geschäftsmodell enthält möglicherweise keine Änderungsbenachrichtigung. Möglicherweise möchten Sie nicht, dass die Benutzerinteraktion das Geschäftsmodell ändert, bis der Benutzer auf eine Schaltfläche OK klickt.Ihr Geschäftsmodell kann Ausnahmen für fehlerhafte Eingaben enthalten, während Sie eine andere Form der Validierung verwenden möchten. Ich bin sicher, du kannst an andere Dinge denken. In der Tat würde ich annehmen, dass Sie die Kapselung in den meisten Fällen wollen, also ist es nicht wirklich "langweilig" in dem Sinne, dass Sie nur viele sinnlose Relay-Methoden schreiben.

0

Genau wie dies geschieht, hängt zum Teil von Ihrem Geschäftsmodell ab, wie wekempf bereits angegeben hat.

Je nachdem, wie Ihre Kundeninformationen in Ihrer Benutzeroberfläche angezeigt werden, haben Sie möglicherweise eine ObservableCollection von Kundenmodustypen in Ihrem ViewModel. Wenn Sie beispielsweise ein Master-/Detailszenario anzeigen, in dem Sie möglicherweise eine Kundenliste haben und unten die Details anzeigen, wenn ein bestimmter Kunde ausgewählt wird.