--- name: avalonia-mvvm description: Implement MVVM patterns using CommunityToolkit.Mvvm in Avalonia applications with ViewModels, Commands, and Dependency Injection license: MIT compatibility: opencode metadata: audience: avalonia-developers framework: avalonia --- # MVVM Patterns in Avalonia Complete guide to MVVM patterns using CommunityToolkit.Mvvm in Avalonia applications. ## What I do - Guide implementation of ViewModels with ObservableObject base class - Show how to create observable properties with [ObservableProperty] attribute - Demonstrate command patterns with [RelayCommand] including async and CanExecute - Explain View-ViewModel mapping using DataTemplates (critical for navigation) - Show dependency injection patterns for passing services to ViewModels ## When to use me Use this skill when you need to: - Create new ViewModels for Avalonia views - Implement observable properties that notify the UI of changes - Add commands to handle user interactions (button clicks, etc.) - Set up navigation patterns with SukiSideMenu or ContentControl - Pass services (like ISukiToastManager) between ViewModels - Implement validation on ViewModel properties ## ViewModel Base Classes ### Basic ViewModel ```cs using CommunityToolkit.Mvvm.ComponentModel; namespace YourApp.ViewModels; public partial class ViewModelBase : ObservableObject { } ``` ### Page ViewModel Base ```cs using CommunityToolkit.Mvvm.ComponentModel; namespace YourApp.ViewModels; public abstract partial class PageViewModelBase : ViewModelBase { public abstract string DisplayName { get; } public abstract string Icon { get; } } ``` ## Observable Properties ### Basic Observable Property ```cs [ObservableProperty] private string _name = ""; ``` ### With Validation ```cs using System.ComponentModel.DataAnnotations; [ObservableProperty] [Required(ErrorMessage = "Name is required")] [MinLength(3, ErrorMessage = "Name must be at least 3 characters")] private string _name = ""; ``` ### With Property Changed Notification ```cs [ObservableProperty] private string _firstName = ""; [ObservableProperty] private string _lastName = ""; public string FullName => $"{FirstName} {LastName}"; partial void OnFirstNameChanged(string value) { OnPropertyChanged(nameof(FullName)); } partial void OnLastNameChanged(string value) { OnPropertyChanged(nameof(FullName)); } ``` ## Commands ### Basic Command ```cs [RelayCommand] private void Save() { // Save logic } ``` ### Command with Parameter ```cs [RelayCommand] private void ButtonClick(string buttonName) { LastButtonClicked = buttonName; } ``` **View:** ```xml