npx skills add ...
npx skills add microsoft/win-dev-skills --skill winui-wpf-migration
Migrate WPF applications to WinUI 3 — namespace replacement (System.Windows → Microsoft.UI.Xaml), control mapping (DataGrid→ListView, WrapPanel→ItemsRepeater, TabControl→TabView), threading (Dispatcher→DispatcherQueue), imaging (System.Drawing→BitmapImage), MVVM conversion to CommunityToolkit.Mvvm, and DynamicResource→ThemeResource. Use when converting WPF code, replacing WPF namespaces, or fixing migration build errors.
npx skills add microsoft/win-dev-skills --skill winui-wpf-migration
Before writing code, inventory WPF-specific APIs:
List: WPF controls used, custom MVVM framework, imaging APIs, threading patterns, Win32 interop.
Immediately set <RootNamespace> in .csproj to match the WPF namespace. Update x:Class in App.xaml, MainWindow.xaml and their code-behind files. Build to verify before porting any code.
| WPF | WinUI 3 |
|---|---|
System.Windows | Microsoft.UI.Xaml |
System.Windows.Controls | Microsoft.UI.Xaml.Controls |
System.Windows.Media | Microsoft.UI.Xaml.Media |
System.Windows.Input | Microsoft.UI.Xaml.Input |
System.Windows.Data | Microsoft.UI.Xaml.Data |
System.Windows.Threading.Dispatcher | Microsoft.UI.Dispatching.DispatcherQueue |
PresentationCore / PresentationFramework | Remove entirely |
| WPF Control | WinUI 3 Equivalent |
|---|---|
DataGrid | ListView with Grid column headers |
WrapPanel | ItemsRepeater + UniformGridLayout |
TabControl | TabView |
StatusBar | Grid row at bottom with TextBlock elements |
Menu / MenuItem | MenuBar / MenuBarItem / MenuFlyoutItem |
ToolBar | CommandBar |
Expander (custom) | Expander (built-in) |
Get via DispatcherQueue.GetForCurrentThread(). No Application.Current.Dispatcher in WinUI 3.
Critical: PresentationCore.dll and System.Windows.Media.Imaging crash the WinUI XAML compiler. This is an architectural incompatibility — no workaround exists.
System.Windows.Media.Imaging references at migration startWindows.Graphics.Imaging (WinRT) or Microsoft.UI.Xaml.Media.Imaging.BitmapImage<UseWPF>true</UseWPF> — it silently corrupts the buildDelete custom ObservableObject/RelayCommand/DelegateCommand. Use CommunityToolkit.Mvvm:
INotifyPropertyChanged base → ObservableObject with [ObservableProperty] partial propertiesRelayCommand → [RelayCommand] attribute{Binding} → {x:Bind Mode=OneWay}DynamicResource → {ThemeResource}.resx → .resw (copy + rename to Strings\en-us\){x:Static} → x:Uid for localized stringsProperties.Resources.Key → ResourceLoader.GetString("Key")PresentationCore, PresentationFramework, or System.Windows.Controls assemblies<UseWPF>true</UseWPF> or <WindowsPackageType>None</WindowsPackageType>Package.appxmanifestApp.xaml / App.xaml.cs — merge WPF code into the WinUI 3 boilerplatewinapp run to launch — never run the .exe directly