MVVM w WPF - Kompletny przewodnik z implementacją i strukturą
mvvm wzorzec w wpf

MVVM w WPF – Kompletny przewodnik z implementacją i strukturą projektu C#

W świecie rozwoju oprogramowania wzorce projektowe odgrywają kluczową rolę w tworzeniu aplikacji, które są zarówno skalowalne, jak i łatwe w utrzymaniu. MVVM (Model-View-ViewModel) to jeden z takich wzorców, szczególnie popularny w aplikacjach z graficznym interfejsem użytkownika (GUI), zwłaszcza w technologii Windows Presentation Foundation (WPF).

W tym artykule omówimy szczegółowo, na czym polega MVVM, jak go zaimplementować w aplikacjach WPF oraz zaproponujemy strukturę folderów dla projektu C# WPF zgodnego z tym wzorcem.

Czym jest MVVM?

MVVM (Model-View-ViewModel) to wzorzec projektowy, który służy do oddzielenia logiki biznesowej i logiki prezentacji od interfejsu użytkownika. Głównym celem jest zwiększenie modularności, reużywalności kodu oraz ułatwienie testowania aplikacji.

Wzorzec MVVM został wprowadzony przez Johna Gossa w Microsoft w celu usprawnienia tworzenia interfejsów użytkownika w WPF. Bazuje on na wcześniejszych wzorcach, takich jak MVC (Model-View-Controller) i MVP (Model-View-Presenter), dostosowując je do specyfiki WPF i mechanizmu data binding.

Komponenty MVVM

Model

Model reprezentuje dane aplikacji oraz jej logikę biznesową. Jest niezależny od interfejsu użytkownika i nie zawiera żadnych informacji o prezentacji danych.

Funkcje

  • Przechowywanie danych aplikacji.
  • Implementacja logiki biznesowej.
  • Obsługa operacji na bazach danych, usługach sieciowych itp.
public class Produkt
{
    public int Id { get; set; }
    public string Nazwa { get; set; }
    public decimal Cena { get; set; }
}

View

View to warstwa odpowiedzialna za prezentację danych użytkownikowi. W WPF są to pliki XAML definiujące interfejs użytkownika.

Funkcje

  • Wyświetlanie danych dostarczonych przez ViewModel.
  • Obsługa interakcji użytkownika (kliknięcia, wpisywanie tekstu).
<Window x:Class="Aplikacja.Views.ProduktView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        Title="Produkt">
    <Grid>
        <TextBox Text="{Binding Nazwa}" />
        <TextBox Text="{Binding Cena}" />
        <Button Content="Zapisz" Command="{Binding ZapiszCommand}" />
    </Grid>
</Window>

ViewModel

ViewModel działa jako pośrednik między Model a View. Zawiera logikę prezentacji i wykorzystuje mechanizmy data binding do komunikacji z widokiem.

Funkcje

  • Udostępnianie danych z Model do View.
  • Obsługa logiki prezentacji (np. walidacja danych).
  • Implementacja komend (ICommand) do obsługi zdarzeń.
public class ProduktViewModel : INotifyPropertyChanged
{
    private Produkt _produkt;
    public string Nazwa
    {
        get { return _produkt.Nazwa; }
        set
        {
            _produkt.Nazwa = value;
            OnPropertyChanged(nameof(Nazwa));
        }
    }

    public decimal Cena
    {
        get { return _produkt.Cena; }
        set
        {
            _produkt.Cena = value;
            OnPropertyChanged(nameof(Cena));
        }
    }

    public ICommand ZapiszCommand { get; }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string nazwaWłasności)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nazwaWłasności));
    }

    public ProduktViewModel()
    {
        _produkt = new Produkt();
        ZapiszCommand = new RelayCommand(Zapisz);
    }

    private void Zapisz(object obj)
    {
        // Logika zapisu produktu
    }
}

MVVM w WPF

Data Binding

Data binding to mechanizm, który automatycznie synchronizuje dane między View i ViewModel. Umożliwia to oddzielenie logiki prezentacji od interfejsu użytkownika.

<TextBox Text="{Binding Nazwa, UpdateSourceTrigger=PropertyChanged}" />

Komendy (ICommand)

ICommand to interfejs w .NET, który służy do obsługi poleceń, czyli akcji, które można wywołać w aplikacji. Jest on szeroko wykorzystywany w wzorcu MVVM (Model-View-ViewModel), szczególnie w aplikacjach WPF, Xamarin, czy MAUI.

Komendy pozwalają na obsługę zdarzeń bezpośrednio w ViewModel, zamiast w kodzie za strony View.

public class RelayCommand : ICommand
{
    private Action<object> _execute;
    private Predicate<object> _canExecute;
    public event EventHandler CanExecuteChanged;

    public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }
    public bool CanExecute(object parameter)
    {
        return _canExecute == null || _canExecute(parameter);
    }
    public void Execute(object parameter)
    {
        _execute(parameter);
    }
}

Powiadomienia (INotifyPropertyChanged)

INotifyPropertyChanged to interfejs w .NET, który umożliwia powiadamianie o zmianach właściwości w obiektach, co jest szczególnie przydatne w aplikacjach wykorzystujących wzorce MVVM (Model-View-ViewModel), takich jak WPF czy Xamarin.

Interfejs INotifyPropertyChanged umożliwia powiadamianie View o zmianach w ViewModel.

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string nazwaWłasności)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nazwaWłasności));
}

Implementacja MVVM w WPF

  1. Utwórz Model: Definiuj klasy reprezentujące dane aplikacji.
  2. Utwórz ViewModel: Implementuj logikę prezentacji, komendy oraz powiadomienia o zmianach.
  3. Utwórz View: Zdefiniuj interfejs użytkownika w XAML, wiążąc kontrolki z właściwościami ViewModel.
  4. Ustaw DataContext: W View ustaw DataContext na instancję odpowiedniego ViewModel.
public partial class ProduktView : Window
{
    public ProduktView()
    {
        InitializeComponent();
        this.DataContext = new ProduktViewModel();
    }
}

Struktura Folderów dla Projektu C# WPF

Aby utrzymać porządek i czytelność w projekcie, warto zorganizować pliki w logiczne foldery. Poniżej proponowana struktura:

/Aplikacja
|-- /Models
|   |-- Produkt.cs
|   |-- Klient.cs
|
|-- /ViewModels
|   |-- ProduktViewModel.cs
|   |-- KlientViewModel.cs
|
|-- /Views
|   |-- ProduktView.xaml
|   |-- ProduktView.xaml.cs
|   |-- KlientView.xaml
|   |-- KlientView.xaml.cs
|
|-- /Commands
|   |-- RelayCommand.cs
|
|-- /Services
|   |-- IDataService.cs
|   |-- DataService.cs
|
|-- /Resources
|   |-- Styles.xaml
|
|-- /App.xaml
|-- /MainWindow.xaml
|-- /MainWindow.xaml.cs

Opis Folderów

  • Models: Zawiera klasy modeli danych.
  • ViewModels: Zawiera klasy ViewModel.
  • Views: Zawiera pliki XAML oraz ich code-behind.
  • Commands: Zawiera klasy implementujące interfejs ICommand.
  • Services: Zawiera klasy usług, np. do komunikacji z bazą danych.
  • Resources: Zawiera zasoby wspólne dla całej aplikacji, takie jak style.

MVVM w słowach

Zalety Stosowania MVVM

  • Rozdzielenie logiki: Ułatwia utrzymanie i rozwój aplikacji.
  • Testowalność: ViewModel i Model można testować niezależnie od interfejsu użytkownika.
  • Reużywalność kodu: Logika może być wykorzystywana w różnych widokach.
  • Czysty kod: Mniej kodu w code-behind View, więcej w testowalnym ViewModel.

Wady i Wyzwania

  • Złożoność: Może być nadmiernie skomplikowany dla prostych aplikacji.
  • Krzywa uczenia się: Wymaga zrozumienia mechanizmów WPF, takich jak data binding i komendy.
  • Debugowanie: Trudniejsze w przypadku błędów w wiązaniach danych.

Najlepsze Praktyki

  • Używaj Frameworków MVVM: Takich jak Prism czy MVVM Light, aby ułatwić implementację.
  • Unikaj kodu w code-behind: Staraj się umieszczać całą logikę w ViewModel.
  • Implementuj interfejsy powiadamiające: INotifyPropertyChanged, INotifyCollectionChanged.
  • Stosuj Dependency Injection: Ułatwia testowanie i zarządzanie zależnościami.

Narzędzia Wspierające MVVM

  • Prism: Framework ułatwiający implementację wzorca MVVM w WPF.
  • MVVM Light Toolkit: Lekki framework dostarczający podstawowych funkcji MVVM.
  • ReactiveUI: Umożliwia programowanie reaktywne w aplikacjach WPF.

Podsumowanie

Wzorzec MVVM jest potężnym narzędziem w tworzeniu aplikacji WPF, pozwalającym na czyste oddzielenie logiki biznesowej od interfejsu użytkownika. Poprzez zrozumienie i właściwe zastosowanie jego zasad, możemy tworzyć aplikacje, które są bardziej skalowalne, łatwiejsze w utrzymaniu i testowaniu.

Bibliografia

Obraz Artur Shamsutdinov z Pixabay

c#mvcwpfwzorce projektowe
Udostępnij:
MVVM w WPF – Kompletny przewodnik z implementacją i strukturą projektu C#
Napisane przez
Michał Wrochna
Co myślisz o tym artykule?
0 reakcji
love
0
like
0
so-so
0
weakly
0
0 komentarzy
Najnowsze komentarze
  • Najnowsze komentarze
  • Najlepsze komentarze
Zaloguj się, aby dodać komentarz.
Prawa zastrzeżone Pi Corp sp. z o.o. copyright 2020-2022