mvvm Tutorial
Erste Schritte mit mvvm
Suche…
Bemerkungen
In diesem Abschnitt erhalten Sie einen Überblick darüber, was mvvm ist und warum ein Entwickler es möglicherweise verwenden möchte.
Es sollte auch alle großen Themen in mvvm erwähnen und auf die verwandten Themen verweisen. Da die Dokumentation für mvvm neu ist, müssen Sie möglicherweise erste Versionen dieser verwandten Themen erstellen.
C # MVVM - Zusammenfassung und vollständiges Beispiel
Zusammenfassung:
MVVM ist ein Architekturmuster, das durch drei verschiedene Komponenten, Modell , Ansicht und ViewModel, dargestellt wird . Um diese drei Schichten zu verstehen, müssen Sie jeweils kurz definieren, gefolgt von einer Erklärung, wie sie zusammenarbeiten.
Modell ist die Schicht, die die Geschäftslogik steuert. Er ruft Informationen aus einer beliebigen Datenquelle ab und speichert sie, um sie vom ViewModel zu verwenden .
ViewModel ist die Ebene, die als Brücke zwischen der Ansicht und dem Modell dient . Möglicherweise werden die Rohdaten aus dem Modell in eine darstellbare Form für die Ansicht umgewandelt . Eine Beispieltransformation wäre: ein boolesches Flag vom Modell in die Zeichenfolge 'True' oder 'False' für die Ansicht.
Ansicht ist die Schicht, die die Schnittstelle der Software (dh die GUI) darstellt. Seine Aufgabe ist es, dem Benutzer die Informationen aus dem ViewModel anzuzeigen und die Änderungen der Informationen an das ViewModel zurückzumelden .
Diese drei Komponenten arbeiten zusammen, indem sie sich auf folgende Weise aufeinander beziehen:
- Die View verweist auf das ViewModel .
- Das ViewModel verweist auf das Modell .
Es ist wichtig zu beachten, dass View und ViewModel eine bidirektionale Kommunikation ( Datenbindung) ermöglichen .
Ein Hauptbestandteil der bidirektionalen Kommunikation (Datenbindung) ist die Schnittstelle INotifyPropertyChanged .
Durch diesen Mechanismus kann die Ansicht die Daten im ViewModel durch Benutzereingaben modifizieren, und das ViewModel kann die Ansicht mit Daten aktualisieren, die möglicherweise über Prozesse im Modell oder mit aktualisierten Daten aus dem Repository aktualisiert wurden.
Die MVVM-Architektur legt großen Wert auf die Trennung der Belange für jede dieser Schichten. Die Trennung der Schichten kommt uns zugute:
- Modularität: Die interne Implementierung jeder Ebene kann geändert oder ausgetauscht werden, ohne dass die anderen beeinflusst werden.
- Erhöhte Testbarkeit: Jede Ebene kann mit gefälschten Daten als Unit-Test getestet werden. Dies ist nicht möglich, wenn der ViewModel -Code in den Code-Behind der View geschrieben wird .
Der Build:
Erstellen Sie ein neues WPF-Anwendungsprojekt
Erstellen Sie drei neue Ordner in Ihrer Lösung: Model , ViewModel und View , und löschen Sie die ursprüngliche MainWindow.xaml
, um einen Neustart zu erhalten.
Erstellen Sie drei neue Elemente, die jeweils einer separaten Ebene entsprechen:
- Rechtsklick auf das Modell Ordner, und fügen Sie eine Klasse Element namens
HelloWorldModel.cs
. - Klicken Sie mit der rechten Maustaste auf den Ordner ViewModel , und fügen Sie ein Klassenelement mit dem Namen
HelloWorldViewModel.cs
. - Klicken Sie mit der rechten Maustaste auf den Ordner Ansicht , und fügen Sie ein Fensterelement (WPF) mit dem Namen
HelloWorldView.xaml
.
Ändern Sie App.xaml
, um auf die neue Ansicht zu verweisen
<Application x:Class="MyMVVMProject.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyMVVMProject"
StartupUri="/View/HelloWorldView.xaml">
<Application.Resources>
</Application.Resources>
</Application>
ViewModel:
Beginnen Sie zuerst mit dem Aufbau des ViewModel . Die Klasse muss die INotifyPropertyChanged
Schnittstelle implementieren, ein PropertyChangedEventHandler
Ereignis deklarieren und eine Methode zum INotifyPropertyChanged
Ereignisses erstellen (Quelle: MSDN: How to Property Property Notification ). Als Nächstes deklarieren Sie ein Feld und eine entsprechende Eigenschaft, und stellen Sie sicher, dass die OnPropertyChanged()
Methode im set
Accessor der Eigenschaft OnPropertyChanged()
. Der Konstruktor im folgenden Beispiel wird verwendet, um zu zeigen, dass das Modell die Daten für ViewModel bereitstellt.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using MyMVVMProject.Model;
namespace MyMVVMProject.ViewModel
{
// Implements INotifyPropertyChanged interface to support bindings
public class HelloWorldViewModel : INotifyPropertyChanged
{
private string helloString;
public event PropertyChangedEventHandler PropertyChanged;
public string HelloString
{
get
{
return helloString;
}
set
{
helloString = value;
OnPropertyChanged();
}
}
/// <summary>
/// Raises OnPropertychangedEvent when property changes
/// </summary>
/// <param name="name">String representing the property name</param>
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public HelloWorldViewModel()
{
HelloWorldModel helloWorldModel = new HelloWorldModel();
helloString = helloWorldModel.ImportantInfo;
}
}
}
Modell:
Als nächstes bauen Sie das Modell . Wie bereits erwähnt, stellt The Model Daten für das ViewModel bereit, indem es aus einem Repository gezogen wird (und zum Speichern in das Repository zurückgeschoben wird). Dies wird im Folgenden mit der GetData()
-Methode demonstriert, die eine einfache List<string>
GetData()
. Die Geschäftslogik wird auch in dieser Schicht angewendet und ist in der ConcatenateData()
-Methode zu sehen. Diese Methode baut den Satz "Hallo, Welt!" Aus der List<string>
, die zuvor aus unserem "Repository" zurückgegeben wurde.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyMVVMProject.Model
{
public class HelloWorldModel
{
private List<string> repositoryData;
public string ImportantInfo
{
get
{
return ConcatenateData(repositoryData);
}
}
public HelloWorldModel()
{
repositoryData = GetData();
}
/// <summary>
/// Simulates data retrieval from a repository
/// </summary>
/// <returns>List of strings</returns>
private List<string> GetData()
{
repositoryData = new List<string>()
{
"Hello",
"world"
};
return repositoryData;
}
/// <summary>
/// Concatenate the information from the list into a fully formed sentence.
/// </summary>
/// <returns>A string</returns>
private string ConcatenateData(List<string> dataList)
{
string importantInfo = dataList.ElementAt(0) + ", " + dataList.ElementAt(1) + "!";
return importantInfo;
}
}
}
Aussicht:
Schließlich kann die Ansicht erstellt werden. Dem Code hinter diesem Beispiel muss nichts hinzugefügt werden, auch wenn dies je nach den Anforderungen der Anwendung variieren kann. Es gibt jedoch einige Zeilen zur XAML. Das Window
benötigt einen Verweis auf den ViewModel
Namespace. Dies wird dem XAML-Namespace xmlns:vm="clr-namespace:MyMVVMProject.ViewModel"
. Als Nächstes benötigt das Fenster einen DataContext
. Dies ist auf <vm:HelloWorldViewModel/>
. Jetzt kann das Etikett (oder die Steuerung Ihrer Wahl) zum Fenster hinzugefügt werden. Der Schlüsselpunkt in dieser Phase ist sicherzustellen, dass Sie die Bindung auf die Eigenschaft des ViewModel setzen , die Sie als Etiketteninhalt anzeigen möchten. In diesem Fall ist dies {Binding HelloString}
.
Es ist wichtig, an die Eigenschaft und nicht an das Feld zu binden, da in diesem Fall die Ansicht nicht die Benachrichtigung erhält, dass sich der Wert geändert hat, da die OnPropertyChanged()
Methode nur das PropertyChangedEvent
für die Eigenschaft und nicht für die OnPropertyChanged()
Feld.
<Window x:Class="MyMVVMProject.View.HelloWorldView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MyMVVMProject.View"
xmlns:vm="clr-namespace:MyMVVMProject.ViewModel"
mc:Ignorable="d"
Title="HelloWorldView" Height="300" Width="300">
<Window.DataContext>
<vm:HelloWorldViewModel/>
</Window.DataContext>
<Grid>
<Label x:Name="label" FontSize="30" Content="{Binding HelloString}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Window>