Dialoge aus dem ViewModel anzeigen, zur Designzeit Daten bereitstellen und mehr

Tipps und Tricks zum MVVM-Pattern
Kommentare

Das Model-View-ViewModel-Pattern ist das „State of the Art“-Pattern für WPF- und Silverlight-Anwendungen. Es wurde bereits in zahlreichen Artikeln beschrieben. Der vorliegende Artikel soll nicht eine weitere Variante sein. Stattdessen wird hier gezeigt, wie sich aus einem ViewModel Dialoge öffnen und zur Designzeit Daten anzeigen lassen. Vorweg zeigt der Artikel auch noch einige Tipps zum Erstellen von ViewModel-Klassen und Verwenden von Commands.

Das Model-View-ViewModel-Pattern (MVVM) hat sich für WPF- und Silverlight-Anwendungen etabliert. Es erlaubt eine strikte Trennung von UI und UI-Logik, indem die eigentliche Logik in eine ViewModel-Klasse gepackt wird. Neben erhöhter Wartbarkeit wird dadurch auch eine erhöhte Testbarkeit und bessere Unterstützung für den Designer-/Entwickerarbeitsfluss gewährleistet. Das UI bindet sich lediglich an Properties der ViewModel-Klasse und enthält ansonsten fast keinen prozeduralen Code. Ist das Pattern richtig umgesetzt, enthält die ViewModel-Klasse keinerlei UI-Elemente und ist somit gefundenes Fressen für Unit Tests. Die ViewModel-Klasse stellt in Form von öffentlichen Properties lediglich Daten und Commands zur Verfügung, an die sich die View binden kann. Abbildung 1 zeigt die typischen drei Komponenten des MVVM-Patterns: die View zum Darstellen, das ViewModel mit Commands und Daten sowie das eigentliche Model, das die Daten enthält. Letzteres ist beispielsweise eine Person-Entität, ein XML-File oder ein sonstiges Datenobjekt.
Abb. 1: Das Model-View-ViewModel-Pattern
Abb. 1: Das Model-View-ViewModel-Pattern
An dieser Stelle wird nicht näher auf die einzelnen Teile des MVVM-Patterns eingegangen, da dieses schon in zahlreichen Artikeln beschrieben wurde [Huber, Thomas Claudius; Pletz, Christoph: „Schöne Aussichten – Das Model-View-ViewModel-Pattern“, in: dot.NET Magazin 10.2007]. Im Folgenden wird gezeigt, für welche Teile eine ViewModel-Klasse erstellt wird, wie RoutedCommands und das MVVM-Pattern zusammenspielen, wie Dialoge aus dem ViewModel angezeigt werden und wie dem Designer Daten zur Verfügung gestellt werden, damit sich eine Anwendung auch in Expression Blend richtig „tunen“ lässt. Diese Szenarien werden an einer kleinen Beispielanwendung demonstriert, deren Funktionalität kurz betrachtet wird, bevor es richtig losgeht.
Die Beispielanwendung
Die in Abbildung 2 dargestellte Anwendung wird für die folgenden Szenarien verwendet. Das Hauptfenster enthält auf der rechten Seite eine Liste zum Anzeigen von Personen. Auf der linken Seite ist die Detailansicht, die den Namen und das Bild der ausgewählten Person anzeigt. In der darüberliegenden Toolbar befinden sich zwei Buttons zum Vor- und Zurücknavigieren. Über das Menü der Anwendung lässt sich der in Abbildung 2 ebenfalls sichtbare Dialog zum Öffnen einer Personenliste anzeigen.
Abb. 2: Die Beispielanwendung für die folgenden Szenarien
Abb. 2: Die Beispielanwendung für die folgenden Szenarien
Die Beispielanwendung ist klein aber fein und verdeutlicht ein paar interessante Aspekte des MVVM-Patterns, die jetzt näher betrachtet werden.
ViewModel per View
MVVM-Einsteiger wissen nicht genau, wofür sie eine ViewModel-Klasse erstellen sollen. Prinzipiell heißt es in der MVVM-Theorie, dass das ViewModel das Model kapselt. Dies ist allerdings nur eine Art des ViewModels. Es wird zudem per View ein ViewModel erstellt, das Commands und Daten für die View bereithält. Es gibt somit zwei Arten von Viewmodels:
  • Ein ViewModel, das eine direkte Beziehung zu einer View hat.
  • Ein ViewModel, das ein Model kapselt und dieses mit weiteren Eigenschaften oder sogar auch Commands ausstattet.
In der hier definierten Beispielanwendung gibt es zwei Ansichten, das Hauptfenster und den Dialog zum Öffnen einer Personenliste. Folglich wird für jede dieser Ansichten ein ViewModel erstellt, das MainViewModel für das Hauptfenster und das OpenListViewModel für den Dialog zum Öffnen der Personenliste. Als Model kommt die Person-Klasse zum Einsatz, die aus einem Entity Data Model stammt. Für dieses Model gibt es somit noch die PersonViewModel- Klasse, die ein Person-Objekt kapselt. Abbildung 3 zeigt die ViewModel-Klassen der Beispielanwendung.
Abb. 3: Die ViewModel-Klassen der Beispielanwendung
Abb. 3: Die ViewModel-Klassen der Beispielanwendung
Wie in Abbildung 3 zu erkennen ist, erben alle ViewModel-Klassen von einer gemeinsamen Basisklasse, die hier ViewModelBase heißt. Diese Basisklasse implementiert das Interface INotifyPropertyChanged und stellt für Subklassen eine Changed- Methode zur Verfügung, um den PropertyChanged-Event auf einfache Weise auszulösen (Listing 1).
public abstract class ViewModelBase : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;
  protected void Changed(string propertyName)
  {
    if (PropertyChanged != null)
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  }
}
Damit wäre das Thema rund um die ViewModel-Klassen geklärt. Pro View ein ViewModel und pro Model ein ViewModel. Üblicherweise ist es so, dass das zu einer View gehörende ViewModel eine Collection von zu einem Model gehörenden ViewModels enthält. So enthält das MainViewModel des hier dargestellten Beispiels eine Persons-Property vom Typ ObservableCollection. Dadurch lässt sich im Hauptfenster eine Liste mit Personen bzw. PersonViewModels anzeigen.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -