Back to Skills

implementing-communitytoolkit-mvvm

verified

Implements MVVM pattern using CommunityToolkit.Mvvm with ObservableProperty attributes. Use when building ViewModels with source generators or implementing commands in WPF/AvaloniaUI.

View on GitHub

Marketplace

dotnet-claude-plugins

christian289/dotnet-with-claudecode

Plugin

wpf-dev-pack

development

Repository

christian289/dotnet-with-claudecode
5stars

wpf-dev-pack/skills/implementing-communitytoolkit-mvvm/SKILL.md

Last Verified

January 23, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/christian289/dotnet-with-claudecode/blob/main/wpf-dev-pack/skills/implementing-communitytoolkit-mvvm/SKILL.md -a claude-code --skill implementing-communitytoolkit-mvvm

Installation paths:

Claude
.claude/skills/implementing-communitytoolkit-mvvm/
Powered by add-skill CLI

Instructions

# CommunityToolkit.Mvvm Code Guidelines

A guide for implementing MVVM pattern using CommunityToolkit.Mvvm in WPF/AvaloniaUI.

## Project Structure

The templates folder contains a .NET 9 WPF project example.

```
templates/
├── WpfMvvmSample.App/           ← WPF Application Project
│   ├── Views/
│   │   ├── MainWindow.xaml
│   │   └── MainWindow.xaml.cs
│   ├── App.xaml
│   ├── App.xaml.cs
│   ├── GlobalUsings.cs
│   └── WpfMvvmSample.App.csproj
└── WpfMvvmSample.ViewModels/    ← ViewModel Class Library (UI framework independent)
    ├── UserViewModel.cs
    ├── GlobalUsings.cs
    └── WpfMvvmSample.ViewModels.csproj
```

## Basic Principle

**Use CommunityToolkit.Mvvm as the default for MVVM structure**

## ObservableProperty Attribute Writing Rules

### Single Attribute - Write Inline

```csharp
// ✅ Good: Single attribute written inline
[ObservableProperty] private string _userName = string.Empty;

[ObservableProperty] private int _age;

[ObservableProperty] private bool _isActive;
```

### Multiple Attributes - ObservableProperty Always Inline

```csharp
// ✅ Good: Multiple attributes, ObservableProperty always inline
[NotifyPropertyChangedRecipients]
[NotifyCanExecuteChangedFor(nameof(SaveCommand))]
[ObservableProperty] private string _email = string.Empty;

[NotifyDataErrorInfo]
[Required(ErrorMessage = "Name is required.")]
[MinLength(2, ErrorMessage = "Name must be at least 2 characters.")]
[ObservableProperty] private string _name = string.Empty;

[NotifyPropertyChangedRecipients]
[NotifyCanExecuteChangedFor(nameof(DeleteCommand))]
[NotifyCanExecuteChangedFor(nameof(UpdateCommand))]
[ObservableProperty] private User? _selectedUser;
```

### Bad Example

```csharp
// ❌ Bad: ObservableProperty on separate line
[NotifyPropertyChangedRecipients]
[NotifyCanExecuteChangedFor(nameof(SaveCommand))]
[ObservableProperty]
private string _email = string.Empty;
```

## Complete ViewModel Example

```csharp
namespace MyApp.ViewModels;

using CommunityToolkit.Mvvm.Compo

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
3051 chars