Freigeben über


Zusammenfassung von Kapitel 18. MVVM

Hinweis

Dieses Buch wurde im Frühjahr 2016 veröffentlicht und seitdem nicht aktualisiert. Wenngleich ein großer Teil des Buchs weiterhin relevante Informationen liefert, sind einige Abschnitte veraltet, und einige Themen sind nicht mehr korrekt oder vollständig.

Eine der besten Möglichkeiten zum Entwerfen einer Anwendung besteht darin, die Benutzeroberfläche vom zugrunde liegenden Code zu trennen, der manchmal als Geschäftslogik bezeichnet wird. Es gibt mehrere Methoden, doch die auf XAML-basierte Umgebungen zugeschnittene ist als „Model View ViewModel“ oder „MVVM“ bekannt.

MVVM-Wechselbeziehungen

Eine MVVM-Anwendung weist drei Ebenen auf:

  • Das Modell (Model) stellt zugrunde liegende Daten bereit, manchmal durch Dateien oder Webzugriffe.
  • Die Ansicht (View) ist die Benutzeroberfläche oder Präsentationsebene, die generell in XAML implementiert wird.
  • Das ViewModel verbindet das Modell und die Ansicht.

Das Modell hat keinen Kontakt zum ViewModel, und das ViewModel hat keinen Kontakt zur Ansicht. Diese drei Ebenen stellen generell mithilfe der folgenden Mechanismen eine Verbindung untereinander her:

Ansicht (View), ViewModel und Ansicht (View)

In vielen kleineren Programmen (und sogar größeren) fehlt häufig das Modell, oder seine Funktionalität ist in das ViewModel integriert.

ViewModels und Datenbindung

Zur Verwendung von Datenbindungen muss ein ViewModel in der Lage sein, die Ansicht zu benachrichtigen, wenn sich eine Eigenschaft des ViewModels geändert hat. Das ViewModel erreicht dies durch Implementierung der INotifyPropertyChanged-Schnittstelle in den System.ComponentModel-Namespace. Dies ist nicht Teil von Xamarin.Forms, sondern von .NET. (In der Regel versuchen ViewModels, die Plattformunabhängigkeit aufrechtzuerhalten.)

Die INotifyPropertyChanged-Schnittstelle deklariert ein einzelnes Ereignis namens PropertyChanged, das die geänderte Eigenschaft angibt.

Eine ViewModel-Uhr

Das DateTimeViewModel in der Bibliothek Xamarin.FormsBook.Toolkit definiert eine Eigenschaft vom Typ DateTime, die sich auf Grundlage eines Timers ändert. Die Klasse implementiert INotifyPropertyChanged und löst immer das PropertyChanged-Ereignis aus, wenn sich die DateTime-Eigenschaft ändert.

Das MvvmClock-Beispiel instanziiert dieses ViewModel und verwendet Datenbindungen an das ViewModel, um aktualisierte Datums- und Uhrzeitinformationen anzuzeigen.

Interaktive Eigenschaften in einem ViewModel

Eigenschaften in einem ViewModel können stärker interaktiv sein, wie von der SimpleMultiplierViewModel-Klasse veranschaulicht, die Teil des SimpleMultiplier-Beispiels ist. Die Datenbindungen stellen Multiplikand- und Multiplikatorwerte aus zwei Slider-Elementen bereit und zeigen das Produkt mit einem Label an. Sie können jedoch umfassende Änderungen an dieser Benutzeroberfläche in XAML vornehmen, ohne dass sich daraus Änderungen am ViewModel oder der CodeBehind-Datei ergeben.

Ein Farb-ViewModel

Das ColorViewModel in der Bibliothek Xamarin.FormsBook.Toolkit integriert die RGB- und HSL-Farbmodelle. Dies wird im HslSliders-Beispiel veranschaulicht:

Dreifacher Screenshot von TK

Optimieren von ViewModel

Der Code in ViewModels kann optimiert werden, indem eine OnPropertyChanged-Methode mithilfe des CallerMemberName-Attributs definiert wird, die den Namen der aufrufenden Eigenschaft automatisch abruft. Die ViewModelBase-Klasse in der Bibliothek Xamarin.FormsBook.Toolkit leistet dies und stellt eine Basisklasse für ViewModels bereit.

Die Befehlsschnittstelle

MVVM arbeitet mit Datenbindungen, und Datenbindungen arbeiten mit Eigenschaften, sodass MVVM bei der Behandlung eines Clicked-Ereignisses eines Button oder eines Tapped-Ereignisses eines TapGestureRecognizer unzureichend erscheint. Damit Ereignisse dieser Art mit ViewModels verarbeitet werden können, unterstützt Xamarin.Forms die Befehlsschnittstelle.

Die Befehlsschnittstelle manifestiert sich im Button mit zwei öffentlichen Eigenschaften:

Um die Befehlsschnittstelle zu unterstützen, muss ein ViewModel eine Eigenschaft vom Typ ICommand definieren, die dann datenmäßig an die Command-Eigenschaft des Button gebunden ist. Die ICommand-Schnittstelle deklariert zwei Methoden und ein Ereignis:

  • Eine Execute-Methode mit einem Argument vom Typ object.
  • Eine CanExecute-Methode mit einem Argument vom Typ object, die bool zurückgibt.
  • Ein CanExecuteChanged-Ereignis.

Intern legt ein ViewModel jede Eigenschaft vom Typ ICommand auf eine Instanz einer Klasse fest, die die ICommand-Schnittstelle implementiert. Durch die Datenbindung ruft der Button anfänglich die CanExecute-Methode auf und deaktiviert sich selbst, wenn die Methode false zurückgibt. Außerdem wird ein Handler für das CanExecuteChanged-Ereignis festgelegt und immer CanExecute aufgerufen, wenn dieses Ereignis ausgelöst wird. Wenn Button aktiviert ist, ruft er immer die Execute-Methode auf, wenn auf Button geklickt wird.

Es kann sein, dass Sie über einige ViewModels verfügen, die älter als Xamarin.Forms sind und die Befehlsschnittstelle ggf. bereits unterstützen. Bei neuen ViewModels, die nur für die Verwendung mit Xamarin.Forms gedacht sind, stellt Xamarin.Forms eine Command-Klasse und eine Command<T>-Klasse bereit, die die ICommand-Schnittstelle implementieren. Der generische Typ ist der Typ des Arguments für die Methoden Execute und CanExecute.

Einfache Methodenausführungen

Das PowersOfThree-Beispiel veranschaulicht, wie Sie die Befehlsschnittstelle in einem ViewModel verwenden. Die PowersViewModel-Klasse definiert zwei Eigenschaften vom Typ ICommand sowie außerdem zwei private Eigenschaften, die an den einfachsten Command-Konstruktor übergeben werden. Das Programm enthält Datenbindungen von diesem ViewModel an die Command-Eigenschaften von zwei Button-Elementen.

Die Button-Elemente können ohne Codeänderungen ganz einfach in XAML durch TapGestureRecognizer-Objekte ersetzt werden.

Fast ein Taschenrechner

Im AddingMachine-Beispiel werden die beiden Methoden Execute und CanExecute von ICommand verwendet. Es wird eine AdderViewModel-Klasse in der Bibliothek Xamarin.FormsBook.Toolkit verwendet. Das ViewModel enthält sechs Eigenschaften vom Typ ICommand. Diese werden vom Command-Konstruktor und vom Command-Konstruktor von Command sowie vom Command<T>-Konstruktor von Command<T> initialisiert. Die numerischen Schlüssel der Rechenmaschine sind alle an die Eigenschaft gebunden, die mit Command<T> initialisiert wird, und ein string-Argument an Execute und CanExecute identifiziert den jeweiligen Schlüssel.

ViewModels und der Anwendungslebenszyklus

Das im AddingMachine-Beispiel verwendete AdderViewModel definiert außerdem zwei Methoden namens SaveState und RestoreState. Diese Methoden werden von der Anwendung aufgerufen, wenn sie in den Standbymodus wechselt, sowie bei Neustarts.