Agent Skill · Dev Proxy

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.

Provider: Dev Proxy Path in repo: plugins/winui/skills/winui-wpf-migration/SKILL.md

Skill body

Migration Process

Step 1: Audit the WPF Source

Before writing code, inventory WPF-specific APIs:

# Find all WPF namespace usage
Select-String -Path (Get-ChildItem -Recurse -Filter "*.cs" | Where-Object { $_.FullName -notlike "*\obj\*" }) -Pattern "System\.Windows\." | Select-Object -Property Filename, LineNumber, Line

List: WPF controls used, custom MVVM framework, imaging APIs, threading patterns, Win32 interop.

Step 2: Create WinUI 3 Project and Align Namespaces

dotnet new winui-mvvm -n <AppName>

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.

Step 3: Replace Namespaces

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

Step 4: Replace Controls

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)

Step 5: Replace Threading

// WPF
Application.Current.Dispatcher.Invoke(() => { /* UI work */ });

// WinUI 3
dispatcherQueue.TryEnqueue(() => { /* UI work */ });

Get via DispatcherQueue.GetForCurrentThread(). No Application.Current.Dispatcher in WinUI 3.

Step 6: Replace Imaging

Critical: PresentationCore.dll and System.Windows.Media.Imaging crash the WinUI XAML compiler. This is an architectural incompatibility — no workaround exists.

Step 7: Replace MVVM Framework

Delete custom ObservableObject/RelayCommand/DelegateCommand. Use CommunityToolkit.Mvvm:

Step 8: Replace Resources

Critical Rules

Post-Migration Validation

# Check for remaining WPF references (should return nothing)
Select-String -Path (Get-ChildItem -Recurse -Filter "*.cs" | Where-Object { $_.FullName -notlike "*\obj\*" }) -Pattern "System\.Windows\."

# Verify packaging preserved
Test-Path "Package.appxmanifest"  # should be True

# Build and run
.\BuildAndRun.ps1