Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -643,8 +643,8 @@
{
"name": "winui3-development",
"source": "winui3-development",
"description": "WinUI 3 and Windows App SDK development agent, instructions, and migration guide. Prevents common UWP API misuse and guides correct WinUI 3 patterns for desktop Windows apps.",
"version": "1.0.0"
"description": "End-to-end WinUI 3 and Windows App SDK toolkit: expert agent, coding instructions, UWP-to-WinUI 3 migration guide, MVVM Toolkit reference, plus CLIs for packaging/debugging (winapp) and Microsoft Store publishing (msstore). Covers the full write → package → publish lifecycle for desktop Windows apps and prevents common UWP API misuse.",
"version": "1.2.0"
}
]
}
1 change: 1 addition & 0 deletions docs/README.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-instructions) for guidelines on
| [ColdFusion Coding Standards](../instructions/coldfusion-cfm.instructions.md)<br />[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fcoldfusion-cfm.instructions.md)<br />[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fcoldfusion-cfm.instructions.md) | ColdFusion cfm files and application patterns |
| [ColdFusion Coding Standards for CFC Files](../instructions/coldfusion-cfc.instructions.md)<br />[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fcoldfusion-cfc.instructions.md)<br />[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fcoldfusion-cfc.instructions.md) | ColdFusion Coding Standards for CFC component and application patterns |
| [CommonMark Markdown](../instructions/markdown.instructions.md)<br />[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fmarkdown.instructions.md)<br />[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fmarkdown.instructions.md) | Markdown formatting aligned to the CommonMark specification (0.31.2) |
| [CommunityToolkit.Mvvm (MVVM Toolkit)](../instructions/mvvm-toolkit.instructions.md)<br />[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fmvvm-toolkit.instructions.md)<br />[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fmvvm-toolkit.instructions.md) | CommunityToolkit.Mvvm (MVVM Toolkit) coding conventions for ViewModels, commands, messaging, validation, and DI across WPF, WinUI 3, .NET MAUI, Uno Platform, and Avalonia. |
| [Comprehensive Guide: Converting Spring Boot Cassandra Applications to use Azure Cosmos DB with Spring Data Cosmos (spring-data-cosmos)](../instructions/convert-cassandra-to-spring-data-cosmos.instructions.md)<br />[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fconvert-cassandra-to-spring-data-cosmos.instructions.md)<br />[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fconvert-cassandra-to-spring-data-cosmos.instructions.md) | Step-by-step guide for converting Spring Boot Cassandra applications to use Azure Cosmos DB with Spring Data Cosmos |
| [Containerization & Docker Best Practices](../instructions/containerization-docker-best-practices.instructions.md)<br />[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fcontainerization-docker-best-practices.instructions.md)<br />[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fcontainerization-docker-best-practices.instructions.md) | Comprehensive best practices for creating optimized, secure, and efficient Docker images and managing containers. Covers multi-stage builds, image layer optimization, security scanning, and runtime best practices. |
| [Context Engineering](../instructions/context-engineering.instructions.md)<br />[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fcontext-engineering.instructions.md)<br />[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/instructions?url=vscode-insiders%3Achat-instructions%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Finstructions%2Fcontext-engineering.instructions.md) | Guidelines for structuring code and projects to maximize GitHub Copilot effectiveness through better context management |
Expand Down
2 changes: 1 addition & 1 deletion docs/README.plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,4 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-plugins) for guidelines on how t
| [testing-automation](../plugins/testing-automation/README.md) | Comprehensive collection for writing tests, test automation, and test-driven development including unit tests, integration tests, and end-to-end testing strategies. | 9 items | testing, tdd, automation, unit-tests, integration, playwright, jest, nunit |
| [typescript-mcp-development](../plugins/typescript-mcp-development/README.md) | Complete toolkit for building Model Context Protocol (MCP) servers in TypeScript/Node.js using the official SDK. Includes instructions for best practices, a prompt for generating servers, and an expert chat mode for guidance. | 2 items | typescript, mcp, model-context-protocol, nodejs, server-development |
| [typespec-m365-copilot](../plugins/typespec-m365-copilot/README.md) | Comprehensive collection of prompts, instructions, and resources for building declarative agents and API plugins using TypeSpec for Microsoft 365 Copilot extensibility. | 3 items | typespec, m365-copilot, declarative-agents, api-plugins, agent-development, microsoft-365 |
| [winui3-development](../plugins/winui3-development/README.md) | WinUI 3 and Windows App SDK development agent, instructions, and migration guide. Prevents common UWP API misuse and guides correct WinUI 3 patterns for desktop Windows apps. | 2 items | winui, winui3, windows-app-sdk, xaml, desktop, windows |
| [winui3-development](../plugins/winui3-development/README.md) | End-to-end WinUI 3 and Windows App SDK toolkit: expert agent, coding instructions, UWP-to-WinUI 3 migration guide, MVVM Toolkit reference, plus CLIs for packaging/debugging (winapp) and Microsoft Store publishing (msstore). Covers the full write → package → publish lifecycle for desktop Windows apps and prevents common UWP API misuse. | 5 items | winui, winui3, windows-app-sdk, xaml, desktop, windows, mvvm, msix, microsoft-store |
1 change: 1 addition & 0 deletions docs/README.skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-skills) for guidelines on how to
| [model-recommendation](../skills/model-recommendation/SKILL.md)<br />`gh skills install github/awesome-copilot model-recommendation` | Analyze chatmode or prompt files and recommend optimal AI models based on task complexity, required capabilities, and cost-efficiency | None |
| [msstore-cli](../skills/msstore-cli/SKILL.md)<br />`gh skills install github/awesome-copilot msstore-cli` | Microsoft Store Developer CLI (msstore) for publishing Windows applications to the Microsoft Store. Use when asked to configure Store credentials, list Store apps, check submission status, publish submissions, manage package flights, set up CI/CD for Store publishing, or integrate with Partner Center. Supports Windows App SDK/WinUI, UWP, .NET MAUI, Flutter, Electron, React Native, and PWA applications. | None |
| [multi-stage-dockerfile](../skills/multi-stage-dockerfile/SKILL.md)<br />`gh skills install github/awesome-copilot multi-stage-dockerfile` | Create optimized multi-stage Dockerfiles for any language or framework | None |
| [mvvm-toolkit](../skills/mvvm-toolkit/SKILL.md)<br />`gh skills install github/awesome-copilot mvvm-toolkit` | CommunityToolkit.Mvvm (the MVVM Toolkit) reference for ViewModels, source generators ([ObservableProperty], [RelayCommand], [NotifyPropertyChangedFor], [NotifyCanExecuteChangedFor], [NotifyDataErrorInfo], [NotifyPropertyChangedRecipients]), base classes (ObservableObject / ObservableValidator / ObservableRecipient), commands (RelayCommand / AsyncRelayCommand), Messenger (WeakReferenceMessenger / StrongReferenceMessenger / IRecipient<T> / RequestMessage<T>), and Microsoft.Extensions.DependencyInjection integration. Use across WPF, WinUI 3, MAUI, Uno, Avalonia, and any .NET Standard 2.0+ XAML stack. | `references/dependency-injection.md`<br />`references/end-to-end-walkthrough.md`<br />`references/messenger-patterns.md`<br />`references/relaycommand-cookbook.md`<br />`references/source-generators.md`<br />`references/troubleshooting.md`<br />`references/validation.md` |
| [my-issues](../skills/my-issues/SKILL.md)<br />`gh skills install github/awesome-copilot my-issues` | List my issues in the current repository | None |
| [my-pull-requests](../skills/my-pull-requests/SKILL.md)<br />`gh skills install github/awesome-copilot my-pull-requests` | List my pull requests in the current repository | None |
| [nano-banana-pro-openrouter](../skills/nano-banana-pro-openrouter/SKILL.md)<br />`gh skills install github/awesome-copilot nano-banana-pro-openrouter` | Generate or edit images via OpenRouter with the Gemini 3 Pro Image model. Use for prompt-only image generation, image edits, and multi-image compositing; supports 1K/2K/4K output. | `assets/SYSTEM_TEMPLATE`<br />`scripts/generate_image.py` |
Expand Down
145 changes: 145 additions & 0 deletions instructions/mvvm-toolkit.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
description: 'CommunityToolkit.Mvvm (MVVM Toolkit) coding conventions for ViewModels, commands, messaging, validation, and DI across WPF, WinUI 3, .NET MAUI, Uno Platform, and Avalonia.'
applyTo: '**/*.cs, **/*.xaml, **/*.csproj'
---

# CommunityToolkit.Mvvm (MVVM Toolkit)

These rules apply whenever a project references `CommunityToolkit.Mvvm`.
For deep reference and end-to-end examples, load the `mvvm-toolkit` skill.

## Package & language

- Reference `CommunityToolkit.Mvvm` 8.x (or newer) in `.csproj`. Do not
install the legacy `Microsoft.Toolkit.Mvvm` (7.x) for new projects.
- C# `LangVersion` must support source generators (default in modern SDKs).

## ViewModel base class

- Inherit ViewModels from `ObservableObject` by default.
- Use `ObservableValidator` only when the ViewModel needs
`INotifyDataErrorInfo` (forms, settings, input validation).
- Use `ObservableRecipient` only when the ViewModel sends or receives
`IMessenger` messages.
- Never hand-implement `INotifyPropertyChanged` when one of the toolkit
base classes can be used. If the type cannot inherit from a toolkit base
(e.g., a custom control), apply the class-level `[ObservableObject]` or
`[INotifyPropertyChanged]` attribute instead.

## Properties

- Declare every type that uses `[ObservableProperty]` as `partial` (and
every enclosing type, if nested).
- Apply `[ObservableProperty]` to private fields named `name`, `_name`, or
`m_name` — never PascalCase. Let the generator emit the public property.
- Do not write manual `SetProperty(ref field, value)` boilerplate when the
field qualifies for `[ObservableProperty]`.
- Use `[NotifyPropertyChangedFor(nameof(Derived))]` to raise change
notifications for derived/computed properties.
- Use `[NotifyCanExecuteChangedFor(nameof(XxxCommand))]` so commands
re-evaluate `CanExecute` when their inputs change.
- Implement `OnXxxChanging` / `OnXxxChanged` partial-method hooks for
side-effects on property changes — do not subscribe to your own
`PropertyChanged` event.
- Use `[property: SomeAttribute]` to forward an attribute (e.g.,
`[JsonIgnore]`, `[JsonPropertyName(...)]`) onto the generated property.

## Commands

- Use `[RelayCommand]` on instance methods over manually constructed
`RelayCommand` / `AsyncRelayCommand` instances.
- `[RelayCommand]` methods must return `void` or `Task` (or `Task<T>`).
Never use `async void` — exceptions become unobserved.
- For cancellable async work, declare a `CancellationToken` parameter and
optionally set `IncludeCancelCommand = true` to expose a paired
`XxxCancelCommand`.
- Use `CanExecute = nameof(...)` plus `[NotifyCanExecuteChangedFor]` on the
inputs to keep button enable/disable state in sync.
- Default `AllowConcurrentExecutions` to `false` (the default). Only set
`true` when overlapping invocations are explicitly safe and intended.
- Default error policy is await-and-rethrow. Only set
`FlowExceptionsToTaskScheduler = true` when the UI binds to
`ExecutionTask` to render error states.

## Messaging

- Default to `WeakReferenceMessenger.Default`. Only switch to
`StrongReferenceMessenger.Default` when profiling shows the messenger is
hot, and document the lifetime guarantees.
- Register handlers with the `(recipient, message)` lambda form using the
`static` modifier — never capture `this` in the lambda.
- Prefer `IRecipient<TMessage>` interfaces on `ObservableRecipient`
ViewModels so `RegisterAll(this)` wires everything automatically when
`IsActive = true`.
- Set `IsActive = true` on activation (e.g., `OnNavigatedTo`) and
`IsActive = false` on deactivation (e.g., `OnNavigatedFrom`).
- Inheritance is not considered when delivering messages — register each
concrete message type explicitly.
- Use channel tokens (the `int` / `string` / `Guid` overloads) to scope
messages to a sub-system or window when more than one consumer would
otherwise collide.

## Dependency injection

- Use `Microsoft.Extensions.DependencyInjection` for service and ViewModel
registration. Prefer the .NET Generic Host
(`Host.CreateDefaultBuilder()`) so configuration, logging, and scope
validation are wired automatically.
- Register services and ViewModels in the composition root (typically
`App.xaml.cs`). Resolve the page's root ViewModel from DI in the page
constructor or via the navigation framework.
- Inject services and child ViewModels through constructors. Do not call
`Ioc.Default.GetService<T>()` from inside ViewModels, services, or any
type the DI container can construct.
- Lifetimes:
- `AddSingleton<T>()` — shell/main-window VMs, settings, file/HTTP
services, the shared `IMessenger`.
- `AddTransient<T>()` — per-page or per-document VMs.
- `AddScoped<T>()` — only with explicit `IServiceScope` usage; rarely
needed in client apps.
- Register `IMessenger` once
(`services.AddSingleton<IMessenger>(WeakReferenceMessenger.Default)`)
and inject it via `ObservableRecipient(messenger)` constructors.

## Validation

- Use `ObservableValidator` plus `[NotifyDataErrorInfo]` and DataAnnotation
attributes (`[Required]`, `[Range]`, `[EmailAddress]`, `[MinLength]`,
`[MaxLength]`, `[CustomValidation]`).
- Call `ValidateAllProperties()` before submitting a form; check
`HasErrors` and bail out if `true`.
- Reset error state with `ClearAllErrors()` after a successful submit or
when resetting a form.
- For cross-property rules, call `ValidateProperty(value, nameof(Other))`
from the changed property's `OnXxxChanged` hook.

## XAML

- For WinUI 3 / UWP, prefer `{x:Bind}` (compiled bindings) over
`{Binding}`. Set `Mode=OneWay` or `Mode=TwoWay` explicitly — `{x:Bind}`
defaults to `OneTime`.
- Bind `Command="{x:Bind ViewModel.SaveCommand}"` directly to the
generated command property.
- Bind async-command status (`IsRunning`, `ExecutionTask.Status`,
`ExecutionTask.Exception`) to surface progress/errors instead of
blocking the UI thread.

## Things to avoid

- `[ObservableProperty] private string Name;` — PascalCase field collides
with the generated property; use lowerCamel.
- Manual `RaisePropertyChanged(nameof(X))` calls alongside
`[ObservableProperty]` — produces duplicate notifications.
- `Ioc.Default.GetService<T>()` from inside a ViewModel constructor —
hides dependencies, breaks unit tests.
- `StrongReferenceMessenger` without `OnDeactivated` / `UnregisterAll` —
pins recipients and leaks them.
- Capturing `this` in messenger lambdas — closure allocation and
lifetime confusion. Always use `(r, m) => r.OnX(m)` with `static`.
- `async void` on `[RelayCommand]` methods — return `Task` instead.
- Mutating the same reference held by an `[ObservableProperty]` field —
the equality comparer returns `true` and no change notification fires.
Replace the instance instead.
- Inheriting from both `ObservableValidator` and `ObservableRecipient` —
not possible; use composition (inject `IMessenger` or implement
validation manually).
Loading
Loading