$npx -y skills add managedcode/dotnet-skills --skill wpfBuild and modernize WPF applications on .NET with correct XAML, data binding, commands, threading, styling, and Windows desktop migration decisions. USE FOR: working on WPF UI, MVVM, binding, commands, or desktop modernization; migrating WPF from .NET Framework to .NET; integrati
| 1 | # WPF |
| 2 | |
| 3 | ## Trigger On |
| 4 | |
| 5 | - working on WPF UI, MVVM, binding, commands, or desktop modernization |
| 6 | - migrating WPF from .NET Framework to .NET |
| 7 | - integrating newer Windows capabilities into a WPF app |
| 8 | - implementing data binding, styles, templates, or control customization |
| 9 | |
| 10 | ## Documentation |
| 11 | |
| 12 | - [WPF Overview](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/overview/) |
| 13 | - [Data Binding Overview](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/) |
| 14 | - [MVVM Toolkit Introduction](https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/) |
| 15 | - [Styles and Templates](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/styles-templates-overview) |
| 16 | - [Migration Guide](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/migration/) |
| 17 | |
| 18 | ### References |
| 19 | |
| 20 | - [patterns.md](references/patterns.md) - MVVM patterns, binding patterns, command patterns, and reusable architectural approaches |
| 21 | - [anti-patterns.md](references/anti-patterns.md) - Common WPF mistakes and how to avoid them |
| 22 | |
| 23 | ## Workflow |
| 24 | |
| 25 | 1. **Confirm Windows-only scope** — WPF is Windows-only even when the wider .NET stack is cross-platform |
| 26 | 2. **Apply MVVM pattern** — keep views dumb, logic in ViewModels, use commands |
| 27 | 3. **Manage data binding explicitly** — choose correct binding modes, validate at runtime |
| 28 | 4. **Use styles and templates deliberately** — keep UI composable, avoid page-specific hacks |
| 29 | 5. **Handle threading correctly** — use Dispatcher for UI updates, async/await for long operations |
| 30 | 6. **Validate both designer and runtime** — XAML composition failures often surface only at runtime |
| 31 | |
| 32 | ## Current Upstream Notes |
| 33 | |
| 34 | - The July 2026 WPF overview refresh reiterates WPF as a Windows desktop UI stack with XAML, data binding, styling, templates, resources, and vector/rich-media composition. Keep WPF-specific guidance separate from WinUI or MAUI unless the task is explicitly a migration or comparison. |
| 35 | - For modernization work, check both `.NET Framework` compatibility constraints and current .NET desktop migration docs before moving project files or XAML resource dictionaries. |
| 36 | |
| 37 | ## Project Structure |
| 38 | |
| 39 | ``` |
| 40 | MyWpfApp/ |
| 41 | ├── MyWpfApp/ |
| 42 | │ ├── App.xaml # Application entry |
| 43 | │ ├── MainWindow.xaml # Main window |
| 44 | │ ├── Views/ # XAML views/windows |
| 45 | │ ├── ViewModels/ # MVVM ViewModels |
| 46 | │ ├── Models/ # Domain models |
| 47 | │ ├── Services/ # Business logic |
| 48 | │ ├── Converters/ # Value converters |
| 49 | │ ├── Resources/ # Styles, templates, dictionaries |
| 50 | │ └── Controls/ # Custom controls |
| 51 | └── MyWpfApp.Tests/ |
| 52 | ``` |
| 53 | |
| 54 | ## MVVM Pattern |
| 55 | |
| 56 | ### ViewModel with MVVM Toolkit |
| 57 | ```csharp |
| 58 | public partial class CustomersViewModel : ObservableObject |
| 59 | { |
| 60 | private readonly ICustomerService _customerService; |
| 61 | |
| 62 | [ObservableProperty] |
| 63 | private ObservableCollection<Customer> _customers = []; |
| 64 | |
| 65 | [ObservableProperty] |
| 66 | [NotifyCanExecuteChangedFor(nameof(SaveCommand))] |
| 67 | private Customer? _selectedCustomer; |
| 68 | |
| 69 | [ObservableProperty] |
| 70 | [NotifyCanExecuteChangedFor(nameof(RefreshCommand))] |
| 71 | private bool _isLoading; |
| 72 | |
| 73 | public CustomersViewModel(ICustomerService customerService) |
| 74 | { |
| 75 | _customerService = customerService; |
| 76 | } |
| 77 | |
| 78 | [RelayCommand(CanExecute = nameof(CanRefresh))] |
| 79 | private async Task RefreshAsync() |
| 80 | { |
| 81 | IsLoading = true; |
| 82 | try |
| 83 | { |
| 84 | var items = await _customerService.GetAllAsync(); |
| 85 | Customers = new ObservableCollection<Customer>(items); |
| 86 | } |
| 87 | finally |
| 88 | { |
| 89 | IsLoading = false; |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | private bool CanRefresh() => !IsLoading; |
| 94 | |
| 95 | [RelayCommand(CanExecute = nameof(CanSave))] |
| 96 | private async Task SaveAsync() |
| 97 | { |
| 98 | if (SelectedCustomer is null) return; |
| 99 | await _customerService.SaveAsync(SelectedCustomer); |
| 100 | } |
| 101 | |
| 102 | private bool CanSave() => SelectedCustomer is not null; |
| 103 | } |
| 104 | ``` |
| 105 | |
| 106 | ### View Binding |
| 107 | ```xml |
| 108 | <Window x:Class="MyWpfApp.Views.CustomersView" |
| 109 | xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
| 110 | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
| 111 | xmlns:vm="clr-namespace:MyWpfApp.ViewModels" |
| 112 | d:DataContext="{d:DesignInstance Type=vm:CustomersViewModel}"> |
| 113 | |
| 114 | <Grid> |
| 115 | <Grid.RowDefinitions> |
| 116 | <RowDefinition Height="Auto"/> |
| 117 | <RowDefinition Heigh |