So verwenden Sie MVVM in einer Universal Windows App

Das Model-View-ViewModel (MVVM) -Muster hilft Entwicklern, die Geschäfts- und Präsentationslogik einer Anwendung von ihrer Benutzeroberfläche zu trennen. Die klare Trennung zwischen Anwendungslogik und Benutzeroberfläche hilft bei der Lösung von Entwicklungs- und Designproblemen und erleichtert das Testen, Verwalten und Entwickeln einer Anwendung. Dadurch kann auch die Wiederverwendbarkeit von Code verbessert werden, und mehrere Entwickler können leichter zusammenarbeiten, wenn sie an demselben Projekt arbeiten.

1. Einleitung

Unter Verwendung des MVVM-Musters sind die Benutzeroberfläche der Anwendung und die zugrunde liegende Präsentations- und Geschäftslogik in drei Komponenten unterteilt:

  • Das Aussicht Komponente kapselt die Benutzeroberfläche und die Logik der Benutzeroberfläche.
  • Das Modell anzeigen Komponente kapselt Präsentationslogik und -status.
  • Das Modell- Die Schicht kapselt die Geschäftslogik und die Daten der Anwendung.

Für das Implementieren des MVVM-Musters in einer Windows-Anwendung stehen mehrere Frameworks zur Verfügung. Welcher Rahmen für Ihr Projekt am besten geeignet ist, hängt von Ihren Anforderungen ab. Für dieses Tutorial verwenden wir MVVM Light, ein beliebtes und benutzerfreundliches MVVM-Framework.

In diesem Lernprogramm erfahren Sie, wie Sie eine Universal Windows-App mit MVVM Light-Unterstützung erstellen. Du wirst lernen wie:

  • Erstellen Sie eine Universal Windows-App und fügen Sie Unterstützung für MVVM Light hinzu
  • Implementiere die Verzeichnisstruktur
  • Fügen Sie die Ansichtsmodellebene hinzu
  • den Datenkontext verbinden
  • Implementieren Sie den Nachrichtendienst, um Nachrichten zwischen Ansichtsmodellen weiterzuleiten

2. Projekteinrichtung

Schritt 1: Erstellen Sie eine Universal Windows App

Beginnen wir mit der Erstellung einer Universal Windows App. Wählen Neues Projekt von dem Datei Menü in Visual Studio. Erweitern Vorlagen > Visuelle C # > Windows > Windows 8 > Universal und wählen Sie Leere App (Universal Windows 8.1) aus der Liste der Projektvorlagen. Benennen Sie Ihr Projekt und klicken Sie auf OK um das Projekt zu erstellen.

Dadurch werden zwei neue Apps (Windows Phone 8.1 und Windows 8.1) und ein freigegebenes Projekt erstellt. Die Windows Phone 8.1- und Windows 8.1-Projekte sind plattformspezifische Projekte und für die Erstellung der Anwendungspakete (.appx) verantwortlich, die auf die jeweiligen Plattformen abzielen. Das freigegebene Projekt ist ein Container für Code, der auf beiden Plattformen ausgeführt wird.

Schritt 2: Fügen Sie die MVVM Light-Unterstützung hinzu

Klicken Sie mit der rechten Maustaste auf den Namen der Lösung Lösungsforscher und wählen Sie Verwalten Sie Nuget-Pakete für die Lösung.

Wähle aus Durchsuche Tab und suchen nach MVVM Light. Wählen Sie das Paket aus MvvmLightLibs aus den Suchergebnissen. Überprüfen Sie die Windows 8.1- und Windows Phone 8.1-Projekte, und klicken Sie auf Installieren um die MVVM Light-Bibliotheken zu den Apps hinzuzufügen.

Zu diesem Zeitpunkt haben Sie Ihren beiden Anwendungen die Unterstützung für MVVM Light hinzugefügt.

3. Projektdateistruktur

Eine universelle Windows-App, die das MVVM-Muster verwendet, erfordert eine bestimmte Verzeichnisstruktur. Die folgende Momentaufnahme zeigt eine mögliche Projektdateistruktur für eine Universal Windows-App.

Lassen Sie mich durch die Projektstruktur einer typischen Univesal Windows-App führen, die das MVVM-Muster verwendet:

  • Steuerelemente: Dieses Verzeichnis enthält wiederverwendbare Steuerelemente der Benutzeroberfläche (anwendungsunabhängige Ansichten). Plattformspezifische Steuerelemente werden direkt dem plattformspezifischen Projekt hinzugefügt.
  • Zeichenketten: Dieses Verzeichnis enthält Zeichenfolgen und Ressourcen für die Anwendungslokalisierung. Das Zeichenketten Das Verzeichnis enthält separate Verzeichnisse für jede unterstützte Sprache. Das en-US Das Verzeichnis enthält beispielsweise Ressourcen für die englische (US) Sprache.
  • Modelle: Im MVVM-Muster kapselt das Modell die Geschäftslogik und die Daten. Im Allgemeinen implementiert das Modell die Funktionen, mit denen die Eigenschaften einfach an die Ansichtsebene gebunden werden können. Dies bedeutet, dass es Benachrichtigungen über "Eigenschaften geändert" und "Sammlung geändert" über die Option unterstützt INotifyPropertyChanged und INotifyCollectionChanged Schnittstellen.
  • ViewModels: Das Ansichtsmodell im MVVM-Muster kapselt die Präsentationslogik und die Daten für die Ansicht. Es hat keinen direkten Bezug zur Ansicht oder zu Kenntnissen über die Implementierung oder den Typ der Ansicht.
  • Konverter: Dieses Verzeichnis enthält die Wertkonverter. Ein Wertkonverter ist eine bequeme Möglichkeit, Daten von einem Typ in einen anderen zu konvertieren. Es implementiert das IValueConverter Schnittstelle.
  • Themes: Das Themes Das Verzeichnis enthält Motivressourcen des Typs ResourceDictionary. Plattformspezifische Ressourcen werden direkt zu einem bestimmten Projekt hinzugefügt, und freigegebene Ressourcen werden zu dem freigegebenen Projekt hinzugefügt.
  • Dienstleistungen: Dieser Abschnitt kann Klassen für Webservice-Anrufe, Navigationsdienste usw. enthalten.
  • Utils Enthält nützliche Funktionen, die in der App verwendet werden können. Beispiele beinhalten AppCacheFileUtilsKonstantenNetzwerkverfügbarkeitGeoLocation, usw.
  • Ansichten: Dieses Verzeichnis enthält die Benutzeroberflächenlayouts. Plattformspezifische Ansichten werden direkt zum plattformspezifischen Projekt hinzugefügt, und gemeinsame Ansichten werden zum freigegebenen Projekt hinzugefügt.

Je nach Ansichtstyp sollte der Name mit enden:

  • Fenster, ein nicht modales Fenster
  • Dialog, ein (modales) Dialogfenster
  • Seite, eine Seitenansicht (meistens in Windows Phone- und Windows Store-Apps verwendet)
  • Aussicht, eine Ansicht, die als Unteransicht in einer anderen Ansicht, Seite, Fenster oder Dialog verwendet wird

Der Name eines Ansichtsmodells setzt sich aus dem Namen der entsprechenden Ansicht und dem Wort „Modell“ zusammen. Die Ansichtsmodelle werden am selben Ort in gespeichert ViewModels Verzeichnis als ihre entsprechenden Ansichten in der Ansichten Verzeichnis.

4. Hinzufügen der Ansichtsmodellebene

Die Ansichtsmodellebene implementiert Eigenschaften und Befehle, an die die Ansicht Daten binden kann und die Ansicht über Statusänderungen durch Änderungsbenachrichtigungsereignisse benachrichtigt. Die Eigenschaften und Befehle, die das Ansichtsmodell bereitstellt, definieren die von der Benutzeroberfläche angebotene Funktionalität. In der folgenden Liste werden die Merkmale, Aufgaben und Verantwortlichkeiten der Ansichtsmodellschicht zusammengefasst:

  • Es koordiniert die Interaktion der Ansicht mit jeder Modellklasse.
  • Das Ansichtsmodell und die Modellklassen haben im Allgemeinen eine Eins-zu-Viele-Beziehung.
  • Es kann Modelldaten konvertieren oder bearbeiten, sodass sie von der Ansicht problemlos verwendet werden können.
  • Es können zusätzliche Eigenschaften definiert werden, um die Ansicht gezielt zu unterstützen.
  • Sie definiert die logischen Zustände, die die Ansicht verwenden kann, um visuelle Änderungen an der Benutzeroberfläche bereitzustellen.
  • Sie definiert die Befehle und Aktionen, die der Benutzer auslösen kann.

In den nächsten Schritten fügen wir der Ansichtsmodellebene zwei Dateien hinzu, ViewModelLocator.cs und MainViewModel.cs.

Schritt 1: Fügen Sie die hinzu MainViewModel Klasse

Klicken Sie zuerst mit der rechten Maustaste auf das freigegebene Projekt und wählen Sie aus Hinzufügen, Neuer Ordner. Benennen Sie den Ordner ViewModels. Klicken Sie anschließend mit der rechten Maustaste auf die Schaltfläche ViewModels Ordner und wählen Sie Hinzufügen, Neuer Gegenstand das hinzufügen MainViewModel Klasse.

Modifiziere den MainViewModel Klasse so aussehen:

öffentliche Klasse MainViewModel: ViewModelBase private Zeichenfolge _helloWorld; öffentliche Zeichenfolge HelloWorld get return _helloWorld;  set Set (() => HelloWorld, ref _helloWorld, Wert);  public MainViewModel () HelloWorld = IsInDesignMode? "Läuft im Designmodus": "Läuft im Laufzeitmodus"; 

Die Klasse enthält eine öffentliche Eigenschaft Hallo Welt vom Typ Schnur. Sie können dem Ansichtsmodell weitere Methoden, beobachtbare Eigenschaften und Befehle hinzufügen.

Schritt 2: Fügen Sie die hinzu ViewModelLocator Klasse

Wir werden eine öffentliche Eigenschaft für alle Ansichtsmodelle in hinzufügen ViewModelLocator Klasse und erstellen Sie eine neue Ressource, die wir im Designer verwenden werden.

Klicken Sie mit der rechten Maustaste auf ViewModels Ordner und wählen Sie Hinzufügen, Neuer Gegenstand. Wählen Sie eine Klasse aus und benennen Sie sie ViewModelLocator.cs. Aktualisieren Sie die ViewModelLocator Klasse wie unten gezeigt.

öffentliche Klasse ViewModelLocator public MainViewModel Main get return ServiceLocator.Current.GetInstance();  static ViewModelLocator () ServiceLocator.SetLocatorProvider (() => SimpleIoc.Default); SimpleIoc.Default.Register(); 

Das ViewModelLocator Klasse enthält eine öffentliche Eigenschaft Main dessen Getter eine Instanz von MainViewModel Klasse. Der Erbauer von ViewModelLocator registriert die MainViewModel Instanz zum SimpleIoc Bedienung.

Als nächstes öffnen App.xaml Datei und fügen Sie eine neue Ressource mit der ViewModelLocator im Designer verwendet werden.

  

5. Verdrahtung des Datenkontexts

Die Ansicht und das Ansichtsmodell können zur Laufzeit auf verschiedene Arten erstellt und zugeordnet werden. Am einfachsten ist es, wenn die Ansicht das entsprechende Ansichtsmodell in XAML instanziiert. Sie können in XAML auch angeben, dass das Ansichtsmodell als Datenkontext der Ansicht festgelegt ist.

  

Wenn der MainPage.xaml Seite wird initialisiert, eine Instanz der MainViewModel wird automatisch erstellt und als Datenkontext der Ansicht festgelegt. Beachten Sie, dass das Ansichtsmodell über einen Konstruktor ohne Parameter verfügen muss, damit dieser Ansatz funktioniert.

Ein anderer Ansatz besteht darin, die View Model-Instanz programmgesteuert im Konstruktor der View zu erstellen und als Datenkontext festzulegen.

public MainPage () InitializeComponent (); this.DataContext = new MainViewModel (); 

Ein anderer Ansatz besteht darin, eine Ansichtsmodellinstanz zu erstellen und sie mithilfe eines Ansichtsmodell-Locators ihrer Ansicht zuzuordnen. In der Beispiel-App verwenden wir die ViewModelLocator Klasse, für die das Ansichtsmodell aufgelöst werden soll MainPage.xaml.

  

Nun wurde der Datenkontext der Ansicht auf den Wert gesetzt MainViewModel Klasse können wir auf seine Eigenschaften in der Ansicht zugreifen. Sie können den Text eines binden Textblock zum Hallo Welt Im Ansichtsmodell definierte Eigenschaft.

6. Kurierdienst

Der Messenger-Dienst in MVVM Light ermöglicht die Kommunikation zwischen Ansichtsmodellen oder zwischen Ansichtsmodellen und Ansichten. Angenommen, Sie haben ein Ansichtsmodell, mit dem einer Suchfunktion Geschäftslogik zur Verfügung gestellt wird, und zwei Ansichtsmodelle auf Ihrer Seite, die die Suche zur Anzeige der Ausgabe verarbeiten möchten. Der Bote wäre der ideale Weg, dies auf lockere Weise zu tun.

Das Ansichtsmodell, das die Suchdaten abruft, würde einfach eine "Such" -Meldung senden, die von jedem Ansichtsmodell verbraucht würde, das gerade registriert war, um die Nachricht zu verbrauchen. Die Vorteile eines Messenger-Dienstes sind:

  • Einfache Kommunikation zwischen Ansichtsmodellen, ohne dass sich jedes Ansichtsmodell gegenseitig kennen muss
  • Mehr Nachrichtenkonsumenten können mit wenig Aufwand hinzugefügt werden
  • Es hält die Ansichtsmodelle einfach

Eine Nachricht senden:

MessengerInstance.Send (Nutzlast, Token);

Um eine Nachricht zu erhalten:

MessengerInstance.Register(dies token, payload => SomeAction (payload));

In der Beispielanwendung senden wir eine Nachricht von MainViewModel, welche erhalten werden von MainPage.xaml. Dies sind die Schritte, die zur Verwendung des Messenger-Dienstes erforderlich sind.

Schritt 1: Erstellen Sie eine Klasse für die zu übergebende Nachricht

Erstellen Sie eine neue Klasse im Projekt und benennen Sie sie ShowMessageDialog.

öffentliche Klasse ShowMessageDialog öffentliche Zeichenfolge Nachricht get; einstellen; 

Schritt 2: Instanziieren Sie Nachrichtenklasse und Broadcast-Nachricht

Im MainViewModel.cs, Eine Instanz von erstellen ShowMessageDialog und benutze die Bote Objekt zum Senden der Nachricht.

privates Objekt ShowMessage () var msg = new ShowMessageDialog Message = "Hello World"; Messenger.Default.Send(msg); null zurückgeben; 

Dadurch wird die Nachricht gesendet. Jetzt müssen Sie nur noch einen Empfänger registrieren und auf die Nachricht antworten.

Schritt 3: Registrieren Sie sich für die Nachricht und behandeln Sie sie, wenn sie empfangen werden

Öffnen MainPage.xaml.cs und registrieren Sie sich für die Nachricht im Konstruktor.

public MainPage () this.InitializeComponent (); Messenger.Default.Register (this (action) => ReceiveMessage (action)); 

Erhalte Nachricht ist eine Methode, die Sie implementieren müssen. Es wird die Botschaft Objekt und verwenden Sie die DialogService ein Dialogfeld anzeigen.

private async void ReceiveMessage (Aktion ShowMessageDialog) DialogService dialogService = new DialogService (); Erwarten Sie dialogService.ShowMessage (action.Message, "Sample Universal App"); 

Schritt 4: Erstellen Sie einen Befehl zum Senden einer Nachricht

Nun, da wir eine Nachricht senden und empfangen können, müssen wir die anrufen Zeige Nachricht Methode. MVVM Light bietet Unterstützung für RelayCommand, die zum Erstellen von Befehlen im Ansichtsmodell verwendet werden kann. Fügen Sie eine öffentliche Eigenschaft hinzu ShowMessageCommand in dem MainViewModel Klasse, die das anruft Zeige Nachricht Methode.

privater RelayCommand _showMessageCommand; public RelayCommand ShowMessageCommand => _showMessageCommand ?? (_showMessageCommand = neuer RelayCommand (ShowMessage));

Als nächstes fügen Sie ein Taste zu MainPage.xaml und binden Sie das ShowMessageCommand zu seinen Befehl Eigentum.

Stellen Sie die App bereit, um zu sehen, ob alles wie erwartet funktioniert. Hier ist eine Momentaufnahme wie MainPage.xaml schaut auf Windows 8.1.

Wenn Sie auf klicken Klick mich Wenn Sie auf die Schaltfläche klicken, wird ein Dialogfeld angezeigt.

Messenger ist eine leistungsstarke Komponente, die die Kommunikation erleichtern kann, aber auch das Debuggen des Codes erschwert, da auf den ersten Blick nicht immer klar ist, welche Objekte eine Nachricht empfangen.

Fazit

Durch die Implementierung des MVVM-Musters haben wir eine klare Trennung zwischen Ansichts-, Ansichtsmodell- und Modellebenen. Normalerweise versuchen wir, das Ansichtsmodell so zu entwickeln, dass es nichts über die Ansicht weiß, die es steuert. Dies hat mehrere Vorteile:

  • Das Entwicklerteam kann unabhängig vom Benutzeroberflächenteam arbeiten.
  • Das Ansichtsmodell kann einfach getestet werden, indem einfach einige Befehle und Methoden aufgerufen werden und der Wert der Eigenschaften festgelegt wird.
  • Sie können Änderungen an der Ansicht vornehmen, ohne sich um die Auswirkungen auf das Ansichtsmodell und das Modell kümmern zu müssen.

Fühlen Sie sich frei, die Quelldateien des Tutorials als Referenz herunterzuladen.