ViewModels in MVVM

ViewModels are a core component of the Model-View-ViewModel (MVVM) architectural pattern in .NET MAUI. They act as intermediaries between the View and the Model, exposing data and commands that the View can bind to.

Purpose of ViewModels

ViewModels are responsible for:

Creating a ViewModel

ViewModels are typically implemented as plain C# classes. They often inherit from ObservableObject (provided by the Community Toolkit.MVVM) or implement INotifyPropertyChanged to notify the View when properties change.

Example: A Simple ViewModel

Let's create a basic ViewModel for a counter feature:


using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System.Windows.Input;

public partial class CounterViewModel : ObservableObject
{
    [ObservableProperty]
    private int _count;

    public ICommand IncrementCommand { get; }

    public CounterViewModel()
    {
        _count = 0;
        IncrementCommand = new RelayCommand(IncrementCount);
    }

    private void IncrementCount()
    {
        Count++;
    }
}
        
Tip: Using [ObservableProperty] attribute from the Community Toolkit.MVVM simplifies property notification by automatically generating the property and its backing field with notification logic.

Data Binding

The View binds to properties and commands exposed by the ViewModel. When a property in the ViewModel changes, the View automatically updates to reflect the new value. Similarly, when a user interacts with a UI element bound to a Command, the ViewModel's corresponding method is executed.

Binding to Properties

In XAML, you can bind to a ViewModel property like this:


<Label Text="{Binding Count}" />
        

Binding to Commands

And bind a button to execute a ViewModel command:


<Button Command="{Binding IncrementCommand}" Text="Increment" />
        

ViewModel Lifecycle and Management

How you manage and instantiate your ViewModels is crucial. Common approaches include:

Important: Ensure that your ViewModels are designed to be stateless where possible, or manage state carefully to avoid issues across navigation or backgrounding.

Common ViewModel Patterns

Displaying Lists

ViewModels often expose collections of data that can be displayed in UI elements like ListView or CollectionView. The collection itself should typically implement INotifyCollectionChanged (e.g., ObservableCollection<T>) to notify the View when items are added, removed, or changed.

Handling Asynchronous Operations

For operations that take time (e.g., network requests, database queries), ViewModels should use asynchronous programming patterns (async/await) and often expose properties to indicate loading states.


[ObservableProperty]
private bool _isLoading;

[ObservableProperty]
private ObservableCollection<string> _items;

public ICommand LoadItemsCommand { get; }

public MyViewModel()
{
    Items = new ObservableCollection<string>();
    LoadItemsCommand = new AsyncRelayCommand(LoadDataAsync);
}

private async Task LoadDataAsync()
{
    IsLoading = true;
    try
    {
        // Simulate fetching data
        await Task.Delay(2000);
        Items.Add("Item 1");
        Items.Add("Item 2");
        Items.Add("Item 3");
    }
    finally
    {
        IsLoading = false;
    }
}
        

Next Steps

Now that you understand ViewModels, explore how Commands facilitate user interaction and how Messengers enable communication between ViewModels.

Note: For a deeper dive into the Community Toolkit.MVVM and its advanced features, refer to its official documentation.