WPF apps run on .NET but use the Windows Presentation Foundation XAML stack. WinUI 3 is the modern replacement. The core challenge for AI migration is that WPF uses System.Windows.* namespaces while WinUI 3 uses Microsoft.UI.Xaml.*, and many controls and windowing APIs need targeted substitutions rather than simple search-and-replace.
gh copilot plugin install winui@awesome-copilot
| WPF | WinUI 3 |
|---|
System.Windows.* | Microsoft.UI.Xaml.* |
System.Windows.Controls.* | Microsoft.UI.Xaml.Controls.* |
System.Windows.Media.* | Microsoft.UI.Xaml.Media.* |
System.Windows.Data.* | Microsoft.UI.Xaml.Data.* |
System.Windows.Input.* | Microsoft.UI.Input.* |
| WPF | WinUI 3 | Notes |
|---|
Window | Microsoft.UI.Xaml.Window | Different API surface |
Grid, StackPanel, Canvas | Unchanged | Same names |
TextBox, Button, CheckBox | Unchanged | Same names, WinUI styling |
ListBox / ListView | ListView | Use ItemsView for new code |
DataGrid | DataGrid (CommunityToolkit) | Add CommunityToolkit.WinUI.Controls.DataGrid |
TabControl | TabView | Different API |
Menu / MenuItem | MenuBar / MenuBarItem | |
ToolBar | CommandBar | |
RichTextBox | RichEditBox | |
WebBrowser | WebView2 | Different API, async |
| WPF | WinUI 3 |
|---|
Dispatcher.Invoke(...) | DispatcherQueue.TryEnqueue(...) |
Dispatcher.BeginInvoke(...) | DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, ...) |
Application.Current.Dispatcher | this.DispatcherQueue |
| WPF | WinUI 3 |
|---|
Window.WindowState | AppWindow.Presenter (use OverlappedPresenter) |
SystemParameters.WorkArea | DisplayArea.GetFromWindowId(...) |
PresentationSource.FromVisual() | WinRT.Interop.WindowNative.GetWindowHandle(window) |
| WPF | WinUI 3 |
|---|
INotifyPropertyChanged | Unchanged |
ObservableCollection<T> | Unchanged |
{Binding} | {x:Bind} preferred (compile-time) |
DependencyProperty | Unchanged |
IValueConverter | Unchanged |
| WPF | WinUI 3 |
|---|
ResourceDictionary | Unchanged |
StaticResource | Unchanged |
DynamicResource | {ThemeResource} for system colors |
SystemColors.WindowBrush | {ThemeResource SystemFillColorSolidNeutralBrush} |
I'm migrating a WPF app to WinUI 3 using the Windows App SDK.
Apply these substitutions:
- System.Windows.* → Microsoft.UI.Xaml.*
- Dispatcher.Invoke / BeginInvoke → DispatcherQueue.TryEnqueue
- Window.WindowState → AppWindow with OverlappedPresenter
- PresentationSource → WinRT.Interop.WindowNative.GetWindowHandle
- DynamicResource for system colors → ThemeResource
- {Binding} → {x:Bind} where possible (compile-time binding)
- ListBox → ListView or ItemsView
- TabControl → TabView
- WebBrowser → WebView2
- DataGrid → CommunityToolkit.WinUI.Controls.DataGrid
Do not use any System.Windows.* namespaces in new code.
Do not use Dispatcher.Invoke — use DispatcherQueue.TryEnqueue.
Flag APIs without a direct WinUI 3 equivalent rather than guessing.
<!-- Before (WPF) -->
<TargetFramework>net10.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<!-- After (WinUI 3) -->
<TargetFramework>net10.0-windows10.0.19041.0</TargetFramework>
<WindowsSdkPackageVersion>10.0.19041.31</WindowsSdkPackageVersion>
dotnet add package Microsoft.WindowsAppSDK
Tell the agent to flag these rather than guess:
- WPF
Adorner layer — no equivalent in WinUI 3
- WPF
FlowDocument / DocumentViewer — use RichEditBox for editable content; no viewer equivalent
- WPF
Viewport3D — use Win2D or DirectX interop
- Air-space / HWND hosting — use
SwapChainPanel or Win32 interop patterns