What Is CommunityToolkit.Mvvm?
CommunityToolkit.Mvvm (the NuGet package CommunityToolkit.Mvvm, formerly Microsoft.Toolkit.Mvvm) is a lightweight, platform-agnostic library maintained by the .NET Foundation community that supplies the core building blocks of the MVVM pattern: ObservableObject, ObservableRecipient, RelayCommand, AsyncRelayCommand, and IMessenger. Unlike heavier frameworks, it has no dependency on any specific UI stack, so the exact same view models compile and run under WPF, .NET MAUI, UWP, WinUI 3, Xamarin.Forms, and Uno Platform without modification.
Cricket analogy: Just as the BCCI's National Cricket Academy gives every state team the same standardized fielding drills so a player trained in Mumbai can slot into any franchise, CommunityToolkit.Mvvm gives every .NET UI stack the same ObservableObject base so a view model written for WPF drops into MAUI unchanged.
Source-Generated Observable Properties
The [ObservableProperty] attribute, applied to a private field inside a partial class, triggers a Roslyn source generator at compile time that emits a public property implementing INotifyPropertyChanged, including PropertyChanging and PropertyChanged event raises and optional dependent-property notifications via [NotifyPropertyChangedFor]. This removes the need to hand-write get/set blocks and SetProperty calls for every bindable field, and because the code is generated rather than reflected at runtime, there is zero runtime performance penalty compared to manually written properties.
Cricket analogy: Like a Hawk-Eye ball-tracking system that automatically computes trajectory and LBW decisions instead of an umpire manually estimating by eye, the source generator automatically produces the property and change notifications instead of a developer manually typing SetProperty calls for each field.
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
public partial class ProductViewModel : ObservableObject
{
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(TotalPrice))]
private decimal unitPrice;
[ObservableProperty]
private int quantity = 1;
public decimal TotalPrice => UnitPrice * Quantity;
[RelayCommand(CanExecute = nameof(CanAddToCart))]
private void AddToCart()
{
// Adds current item to the shopping cart.
}
private bool CanAddToCart() => Quantity > 0 && UnitPrice > 0;
}RelayCommand and Weak-Referenced Messaging
The [RelayCommand] attribute generates an ICommand-backed property (synchronous RelayCommand or, for async methods, AsyncRelayCommand with built-in IsRunning tracking and exception surfacing) from a decorated method, optionally wiring a CanExecute predicate specified via the CanExecute named argument, and the generated command automatically calls NotifyCanExecuteChanged when dependent observable properties change if configured. Separately, IMessenger (implemented by WeakReferenceMessenger or StrongReferenceMessenger) provides a decoupled publish-subscribe channel so unrelated view models can communicate without holding direct references to each other, and the weak-reference variant avoids the memory leaks that plague naive C# event subscriptions.
Cricket analogy: Like a third umpire who only signals a decision review is enabled when specific match conditions are met, [RelayCommand]'s CanExecute predicate only enables the button when the bound condition, such as quantity and price being valid, is true.
CommunityToolkit.Mvvm's source generators require the class to be declared partial, and Visual Studio's IntelliSense fully understands the generated members, so you get accurate autocomplete and 'Go to Definition' even though the property code technically does not exist in the file you are editing.
- CommunityToolkit.Mvvm is platform-agnostic and works identically across WPF, MAUI, UWP, WinUI, and Xamarin.Forms.
- [ObservableProperty] on a private field generates a full INotifyPropertyChanged-compliant public property at compile time via a Roslyn source generator.
- [NotifyPropertyChangedFor] lets one property's change automatically raise notifications for computed properties that depend on it.
- [RelayCommand] generates ICommand-backed properties, with AsyncRelayCommand adding built-in IsRunning state and safe async exception handling.
- CanExecute predicates can be wired declaratively via the CanExecute named argument on [RelayCommand].
- IMessenger (WeakReferenceMessenger or StrongReferenceMessenger) enables decoupled pub-sub communication between view models without direct references.
- Because generation happens at compile time, there is no runtime reflection overhead compared to hand-written MVVM boilerplate.
Practice what you learned
1. What triggers the generation of a public observable property in CommunityToolkit.Mvvm?
2. Why does CommunityToolkit.Mvvm require the containing class to be declared 'partial'?
3. What is the primary advantage of AsyncRelayCommand over a plain RelayCommand?
4. What problem does WeakReferenceMessenger specifically solve compared to plain C# events?
5. Which UI frameworks can consume the exact same CommunityToolkit.Mvvm view model code without modification?
Was this page helpful?
You May Also Like
Prism Framework Basics
An overview of Prism, the modular MVVM application framework offering regions, navigation, module loading, and event aggregation for large WPF and MAUI applications.
Caliburn.Micro Overview
An overview of Caliburn.Micro, the convention-based MVVM framework that automates view-viewmodel binding, actions, and screen conductors with minimal explicit wiring.
MVVM in .NET MAUI
How the MVVM pattern is applied in .NET MAUI using CommunityToolkit.Mvvm, XAML data binding, Shell navigation, and dependency injection to build cross-platform mobile and desktop apps.
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics