Was ist MVVM?

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.

Vergleich: MVVM und MVC

Was ist MVC (Model-View-Controller)?

Komponenten:

  • Model: Enthält die Geschäftslogik und Daten.
  • View: Stellt die Benutzeroberfläche dar.
  • Controller: Vermittler zwischen View und Model, verarbeitet Benutzeraktionen.

Kommunikation:

  • Benutzeraktionen gehen an den Controller.
  • Der Controller aktualisiert das Model.
  • Änderungen im Model werden an die View übergeben.

Was ist MVVM (Model-View-ViewModel)?

Komponenten:

  • Model: Enthält die Geschäftslogik und Daten.
  • View: Stellt die Benutzeroberfläche dar.
  • ViewModel: Vermittler, der die Präsentationslogik enthält und Bindungen zur View unterstützt.

Kommunikation:

  • Starke Datenbindung zwischen View und ViewModel.
  • Änderungen im ViewModel werden automatisch in der View angezeigt.

Hauptunterschiede zwischen MVC und MVVM

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

Diagramme

MVC-Diagramm

MVVM-Diagramm

Fazit

  • MVC: Einfacher, aber eng gekoppelt. Geeignet für kleinere Anwendungen.
  • MVVM: Flexibler und besser testbar. Ideal für komplexere Anwendungen.

UML - MVVM Beispiel

Das Modell (Model)

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
}
  • Einfache Datenpräsentation

Das ViewModel

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");
    }
}
  • Vermittelt zwischen Model und View.
  • Verwendet ReactiveUI für reaktive Bindungen.
dotnet add package ReactiveUI
public 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)}");
    }
}

Die Ansicht (View)

<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>
  • Definiert die Benutzeroberfläche und Bindungen.

Verbindung zwischen View und ViewModel

  • Datenbindung ist der Schlüssel.
  • Das ViewModel stellt Daten und Befehle für die View bereit.
  • AvaloniaUI unterstützt reaktive Datenbindungen für eine nahtlose Integration.

Zusammenfassung

  • MVVM ermöglicht eine klare Trennung von Belangen.
  • AvaloniaUI bietet eine moderne Plattform für die Entwicklung von Desktop-Anwendungen.
  • Die Verwendung von ReactiveUI erleichtert die Entwicklung reaktiver Anwendungen.

MVVM-ClickCounter

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.

📚 Beschreibung

Die Anwendung ist ein einfacher Klickzähler. Sie enthält:

  • Eine Schaltfläche zum Erhöhen des Zählers.
  • Einen Textblock, der den aktuellen Zählerstand anzeigt.

🔍 Was ist MVVM?

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.

Die Hauptkomponenten:

  1. Model:

    • Enthält die Geschäftslogik und die Daten.
    • Im Projekt: Die Klasse CounterModel repräsentiert das Datenmodell mit einer Count-Eigenschaft.
  2. ViewModel:

    • Vermittelt zwischen View und Model.
    • Stellt der View (über Bindings) die Daten und die Logik zur Verfügung.
    • Im Projekt: Die Klasse CounterViewModel enthält die Logik zum Inkrementieren des Zählers und die Bindungen für die View.

Die Hauptkomponenten:

3. View:

  • Die Benutzeroberfläche der Anwendung.
  • Bindet sich an Eigenschaften und Befehle des ViewModels.
  • Im Projekt: Die XAML-Datei MainWindow.xaml definiert die Benutzeroberfläche.

🚀 Wie MVVM in diesem Projekt verwendet wird

  1. Model (CounterModel):

    • Speichert die Zähler-Daten (Count).
    • Kein direkter Bezug zur Benutzeroberfläche.
  2. ViewModel (CounterViewModel):

    • Verwaltet die Geschäftslogik (z. B. Inkrementieren des Zählers).
    • Implementiert INotifyPropertyChanged, um Änderungen im Model an die View weiterzuleiten.
    • Beispiel:
      • Die Methode IncrementCount() erhöht den Zähler.
      • Die Eigenschaft Count informiert die View über Änderungen.
  1. View (MainWindow.xaml):
    • Definiert die Benutzeroberfläche.
    • Bindet sich an die Eigenschaften und Befehle im CounterViewModel.
    • Beispiel:
      • Der TextBlock zeigt den Wert der Count-Eigenschaft an.
      • Die Button-Schaltfläche ruft den Befehl IncrementCount auf.

🛠️ Installation und Ausführung

  1. Projekt einrichten:

    • Klonen Sie dieses Repository:
      git clone \
      git@gitlab.htlwrn.ac.at:HP/mvvm-click-counter-avalonia-c-sharp.git
    • Navigieren Sie in das Projektverzeichnis.
  2. Abhängigkeiten installieren:

    • Stellen Sie sicher, dass .NET installiert ist.
    • Installieren Sie die benötigten AvaloniaUI-Pakete (falls erforderlich).
  3. Projekt ausführen:

    • Kompilieren und starten Sie die Anwendung:
      dotnet run
      

💡 Features

  • Einfacher, inkrementeller Zähler.
  • Klare Trennung von Logik und Benutzeroberfläche durch MVVM.
  • Nutzung von Datenbindung, um die View automatisch zu aktualisieren.

🖼️ Screenshots

Hier ein Beispielbild der Anwendung:

🧪 Tests

  • Unit-Tests können für die ViewModel-Klasse erstellt werden, um sicherzustellen, dass die Geschäftslogik korrekt funktioniert.
  • Beispiel:
    • Testen Sie, ob der Zähler korrekt inkrementiert wird.

📝 Weiterführende Informationen

09d_MVVM

By Harald Haberstroh

09d_MVVM

  • 139