Overview
The Model‑View‑ViewModel (MVVM) pattern separates UI (View) from business logic (ViewModel) and data (Model). In .NET MAUI, MVVM enables clean, testable code and leverages data binding, commands, and dependency injection.
Key Concepts
- BindingContext – the source object for data binding.
- ICommand – encapsulates actions triggered from the UI.
- ObservableObject – provides
INotifyPropertyChanged
implementation.
Getting Started
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
BindingContext = new MainViewModel();
}
}
Data Binding
Bind UI elements directly to ViewModel properties using {Binding}
expressions.
<Label Text="{Binding Greeting}" FontSize="24" />
<Entry Text="{Binding Username, Mode=TwoWay}" Placeholder="Enter name" />
Observable Property
public class MainViewModel : ObservableObject
{
private string _greeting;
public string Greeting
{
get => _greeting;
set => SetProperty(ref _greeting, value);
}
}
Commands
Commands bind UI actions like button clicks to ViewModel logic.
<Button Text="Click Me"
Command="{Binding ClickCommand}"
CommandParameter="Hello" />
public class MainViewModel : ObservableObject
{
public ICommand ClickCommand { get; }
public MainViewModel()
{
ClickCommand = new Command<string>(OnClicked);
}
private void OnClicked(string message)
{
Greeting = $"You clicked: {message}";
}
}
ViewModel Base Class
Use ObservableObject
from CommunityToolkit.Mvvm
or create your own base that implements INotifyPropertyChanged
.
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T backingStore, T value,
[CallerMemberName] string propertyName = "")
{
if (EqualityComparer.Default.Equals(backingStore, value))
return false;
backingStore = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
return true;
}
}
Resources & Styles
Define shared resources in App.xaml
for consistent UI.
<ResourceDictionary>
<Color x:Key="PrimaryColor">#2563EB</Color>
<Style TargetType="Label">
<Setter Property="TextColor" Value="{StaticResource PrimaryColor}" />
</Style>
</ResourceDictionary>