wpf-mvvm

Apply MVVM conventions with CommunityToolkit.Mvvm, ensuring view models are UI-agnostic and ready for the widget shell architecture.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "wpf-mvvm" with this command: npx skills add yosrbennagra/3sc/yosrbennagra-3sc-wpf-mvvm

Wpf Mvvm

Overview

Apply MVVM conventions with CommunityToolkit.Mvvm, ensuring view models are UI-agnostic and ready for the widget shell architecture.

Constraints

  • Target .NET 8

  • CommunityToolkit.Mvvm

  • ViewModel-first navigation (custom service)

  • No Prism, no heavy region manager

Definition of Done (DoD)

  • ViewModel has no WPF dependencies (Window, UserControl, etc.)

  • Commands use [RelayCommand] attribute from CommunityToolkit.Mvvm

  • Observable properties use [ObservableProperty] attribute

  • Async commands have proper cancellation support where applicable

  • ViewModel behavior is covered by unit tests

  • No Application.Current access in ViewModels

  • Services injected via constructor (not resolved in methods)

Core Patterns

ViewModel Base Classes

Base Class Use Case

ObservableObject

Standard ViewModels

ObservableValidator

ViewModels with validation

ObservableRecipient

ViewModels needing messaging

Observable Properties

[ObservableProperty] private string _title = "Widget";

// With property change notification to other properties [ObservableProperty] [NotifyPropertyChangedFor(nameof(CanSave))] private string _name = "";

// With can-execute change notification [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(SaveCommand))] private bool _isValid;

Commands

// Simple command [RelayCommand] private void Refresh() { }

// Async command with cancellation [RelayCommand] private async Task LoadDataAsync(CancellationToken token) { Data = await _service.GetDataAsync(token); }

// Command with can-execute [RelayCommand(CanExecute = nameof(CanSave))] private void Save() { }

private bool CanSave => !string.IsNullOrEmpty(Name);

Async Command Patterns

[RelayCommand] private async Task LoadAsync(CancellationToken token) { IsLoading = true; try { Items = await _service.GetItemsAsync(token); } catch (Exception ex) when (ex is not OperationCanceledException) { ErrorMessage = "Failed to load items"; Log.Error(ex, "Load failed"); } finally { IsLoading = false; } }

Validation

public partial class SettingsViewModel : ObservableValidator { [ObservableProperty] [NotifyDataErrorInfo] [Required(ErrorMessage = "Name is required")] [MinLength(3)] private string _name = "";

[RelayCommand(CanExecute = nameof(CanSave))]
private void Save()
{
    ValidateAllProperties();
    if (!HasErrors)
    {
        // Proceed
    }
}

private bool CanSave => !HasErrors;

}

Navigation (ViewModel-First)

// In Shell or navigation service public void Navigate<TViewModel>() where TViewModel : ObservableObject { var vm = _serviceProvider.GetRequiredService<TViewModel>(); CurrentContent = vm; // DataTemplate maps VM to View }

<!-- In App.xaml or Resources --> <DataTemplate DataType="{x:Type vm:SettingsViewModel}"> <views:SettingsView/> </DataTemplate>

Anti-Patterns

❌ Don't ✅ Do

Reference Window/UserControl in VM Inject INavigationService

Call Application.Current Inject IThemeService, IShellService

Create services in methods Inject via constructor

Use code-behind for business logic Keep logic in ViewModel

Expose ICommand directly Use [RelayCommand]

Testing ViewModels

[Fact] public void Save_WhenValid_CallsService() { var mockService = new Mock<IDataService>(); var vm = new MyViewModel(mockService.Object);

vm.Name = "Valid Name";
vm.SaveCommand.Execute(null);

mockService.Verify(s => s.Save(It.IsAny&#x3C;Data>()), Times.Once);

}

References

  • CommunityToolkit.Mvvm documentation

  • 3SC/ViewModels/ for examples

  • async-patterns skill for async command details

  • input-validation skill for validation patterns

References

  • references/viewmodel-patterns.md for structure patterns.

  • references/commands-and-async.md for command and async guidance.

  • references/validation.md for validation recipes.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

wpf-ui-shell

No summary provided by upstream source.

Repository SourceNeeds Review
General

resilience

No summary provided by upstream source.

Repository SourceNeeds Review
General

data-access

No summary provided by upstream source.

Repository SourceNeeds Review
General

async-patterns

No summary provided by upstream source.

Repository SourceNeeds Review