Migrate a WPF app to WinUI 3

May 21, 2026 · View on GitHub

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.

Install the WPF migration skill

gh copilot plugin install winui@awesome-copilot

API substitution table

Namespaces

WPFWinUI 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.*

Controls

WPFWinUI 3Notes
WindowMicrosoft.UI.Xaml.WindowDifferent API surface
Grid, StackPanel, CanvasUnchangedSame names
TextBox, Button, CheckBoxUnchangedSame names, WinUI styling
ListBox / ListViewListViewUse ItemsView for new code
DataGridDataGrid (CommunityToolkit)Add CommunityToolkit.WinUI.Controls.DataGrid
TabControlTabViewDifferent API
Menu / MenuItemMenuBar / MenuBarItem
ToolBarCommandBar
RichTextBoxRichEditBox
WebBrowserWebView2Different API, async

Threading

WPFWinUI 3
Dispatcher.Invoke(...)DispatcherQueue.TryEnqueue(...)
Dispatcher.BeginInvoke(...)DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, ...)
Application.Current.Dispatcherthis.DispatcherQueue

Windowing and DPI

WPFWinUI 3
Window.WindowStateAppWindow.Presenter (use OverlappedPresenter)
SystemParameters.WorkAreaDisplayArea.GetFromWindowId(...)
PresentationSource.FromVisual()WinRT.Interop.WindowNative.GetWindowHandle(window)

Data binding

WPFWinUI 3
INotifyPropertyChangedUnchanged
ObservableCollection<T>Unchanged
{Binding}{x:Bind} preferred (compile-time)
DependencyPropertyUnchanged
IValueConverterUnchanged

Resources and styles

WPFWinUI 3
ResourceDictionaryUnchanged
StaticResourceUnchanged
DynamicResource{ThemeResource} for system colors
SystemColors.WindowBrush{ThemeResource SystemFillColorSolidNeutralBrush}

Starter prompt

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.

Project file changes

<!-- 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

APIs that don't migrate directly

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