Model-View-ViewModel (MVVM) ist ein Softwarearchitekturmuster. Trennt die Geschäftslogik (Model) von der Benutzeroberfläche (View). ViewModel agiert als Vermittler, der Datenbindungen und Logik verwaltet.
| Merkmal | MVC | MVVM |
|---|---|---|
| Vermittler | Controller | ViewModel |
| Datenbindung | Keine oder manuelle Bindung | Automatische Datenbindung |
| Abhängigkeiten | Enge Kopplung zwischen View und Controller | Lockere Kopplung durch Bindung |
| Testbarkeit | Weniger testbar | Sehr testbar durch ViewModel |
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
}
using System.ComponentModel;
using ReactiveUI;
public class MainViewModel : ReactiveObject {
private Person _person;
public string FirstName {
get => _person.FirstName;
set {
_person.FirstName = value;
this.RaiseAndSetIfChanged(ref _person.FirstName, value);
}
}
public string LastName {
get => _person.LastName;
set {
_person.LastName = value;
this.RaiseAndSetIfChanged(ref _person.LastName, value);
}
}
public MainViewModel() {
_person = new Person("Max", "Mustermann");
}
}
ReactiveUI für reaktive Bindungen.dotnet add package ReactiveUIpublic class Person : INotifyPropertyChanged {
private string _firstName;
private string _lastName;
public Person(string firstName, string lastName) {
_firstName = firstName;
_lastName = lastName;
}
public string FirstName {
get => _firstName;
set {
if (_firstName != value) {
_firstName = value;
OnPropertyChanged(nameof(FirstName));
}
}
}
public string LastName {
get => _lastName;
set {
if (_lastName != value) {
_lastName = value;
OnPropertyChanged(nameof(LastName));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
// Testausgabe bei jeder Änderung
Console.WriteLine($"{propertyName} has been changed to: {GetType().GetProperty(propertyName)?.GetValue(this, null)}");
}
}
<Window xmlns="https://github.com/avaloniaui"
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:vm="clr-namespace:YourNamespace.ViewModels"
mc:Ignorable="d"
Title="MVVM Beispiel" Width="400" Height="200"
x:Class="YourNamespace.Views.MainWindow">
<Window.DataContext>
<vm:MainViewModel/>
</Window.DataContext>
<StackPanel Margin="20">
<TextBlock Text="Vorname:"/>
<TextBox Text="{Binding FirstName}"/>
<TextBlock Text="Nachname:"/>
<TextBox Text="{Binding LastName}"/>
</StackPanel>
</Window>
Ein einfaches plattformübergreifendes Projekt, das mit AvaloniaUI und dem MVVM-Pattern (Model-View-ViewModel) implementiert wurde. Diese Anwendung zeigt, wie das MVVM-Muster genutzt werden kann, um Benutzeroberfläche und Anwendungslogik sauber zu trennen.
Die Anwendung ist ein einfacher Klickzähler. Sie enthält:
MVVM (Model-View-ViewModel) ist ein Softwarearchitekturmuster, das die Benutzeroberfläche (View) von der Anwendungslogik (ViewModel) und den Daten (Model) trennt. Es wird häufig in GUI-Anwendungen verwendet, um die Testbarkeit, Wartbarkeit und Erweiterbarkeit zu verbessern.
Model:
CounterModel repräsentiert das Datenmodell mit einer Count-Eigenschaft.ViewModel:
CounterViewModel enthält die Logik zum Inkrementieren des Zählers und die Bindungen für die View.3. View:
MainWindow.xaml definiert die Benutzeroberfläche.Model (CounterModel):
Count).ViewModel (CounterViewModel):
INotifyPropertyChanged, um Änderungen im Model an die View weiterzuleiten.IncrementCount() erhöht den Zähler.Count informiert die View über Änderungen.CounterViewModel.TextBlock zeigt den Wert der Count-Eigenschaft an.Button-Schaltfläche ruft den Befehl IncrementCount auf.Projekt einrichten:
git clone \
git@gitlab.htlwrn.ac.at:HP/mvvm-click-counter-avalonia-c-sharp.git
Abhängigkeiten installieren:
Projekt ausführen:
dotnet run
git clone \
git@gitlab.htlwrn.ac.at:HP/mvvm-click-counter-avalonia-c-sharp.gitdotnet runHier ein Beispielbild der Anwendung:
CounterModel.cs
int Count
CounterViewModel.cs
INotifyPropertyChanged
Count bereitIncrementCount() erhöht den Zähler und feuert PropertyChanged
MainWindow.xaml und MainWindow.xaml.cs
Count und IncrementCommand bzw. ruft Event-Handler aufDataContext = new CounterViewModel();
DataContext = new CounterViewModel() gesetztCounterModel
Count-Eigenschaft liefert model.Count
Count über BindingIncrementCommand oder Click-Handler aufRaisePropertyChanged("Count") wird ausgelöstPropertyChanged