UWP-to-WinUI 3 migration reference. Maps legacy UWP APIs to correct Windows App SDK equivalents with before/after code snippets. Covers namespace changes, threading (CoreDispatcher to DispatcherQueue), windowing (CoreWindow to AppWindow), dialogs, pickers, sharing, printing, background tasks, and the most common Copilot code generation mistakes.
v1.0Latest
New~2.2kUpdated Jun 26, 2026
WinUI 3 Migration Guide
Use this skill when migrating UWP apps to WinUI 3 / Windows App SDK, or when verifying that generated code uses correct WinUI 3 APIs instead of legacy UWP patterns.
Namespace Changes
All Windows.UI.Xaml.* namespaces move to Microsoft.UI.Xaml.*:
UWP Namespace
WinUI 3 Namespace
Windows.UI.Xaml
Microsoft.UI.Xaml
Windows.UI.Xaml.Controls
Microsoft.UI.Xaml.Controls
Windows.UI.Xaml.Media
Microsoft.UI.Xaml.Media
Windows.UI.Xaml.Input
Microsoft.UI.Xaml.Input
Windows.UI.Xaml.Data
Microsoft.UI.Xaml.Data
Windows.UI.Xaml.Navigation
Microsoft.UI.Xaml.Navigation
Windows.UI.Xaml.Shapes
Microsoft.UI.Xaml.Shapes
Windows.UI.Composition
Microsoft.UI.Composition
Windows.UI.Input
Microsoft.UI.Input
Windows.UI.Colors
Microsoft.UI.Colors
Windows.UI.Text
Microsoft.UI.Text
Windows.UI.Core
Microsoft.UI.Dispatching (for dispatcher)
Top 3 Most Common Copilot Mistakes
1. ContentDialog Without XamlRoot
// ❌ WRONG — Throws InvalidOperationException in WinUI 3var dialog = new ContentDialog
{
Title = "Error",
Content = "Something went wrong.",
CloseButtonText = "OK"
};
await dialog.ShowAsync();
// ✅ CORRECT — Set XamlRoot before showingvar dialog = new ContentDialog
{
Title = "Error",
Content = "Something went wrong.",
CloseButtonText = "OK",
XamlRoot = this.Content.XamlRoot // Required in WinUI 3
};
await dialog.ShowAsync();
2. MessageDialog Instead of ContentDialog
// ❌ WRONG — UWP API, not available in WinUI 3 desktopvar dialog = new Windows.UI.Popups.MessageDialog("Are you sure?", "Confirm");
await dialog.ShowAsync();
// ✅ CORRECT — Use ContentDialogvar dialog = new ContentDialog
{
Title = "Confirm",
Content = "Are you sure?",
PrimaryButtonText = "Yes",
CloseButtonText = "No",
XamlRoot = this.Content.XamlRoot
};
var result = await dialog.ShowAsync();
if (result == ContentDialogResult.Primary)
{
// User confirmed
}
3. CoreDispatcher Instead of DispatcherQueue
// ❌ WRONG — CoreDispatcher does not exist in WinUI 3await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
StatusText.Text = "Done";
});
// ❌ WRONG — UWP style, no window handlevar picker = new FileOpenPicker();
picker.FileTypeFilter.Add(".txt");
varfile = await picker.PickSingleFileAsync();
// ✅ CORRECT — Initialize with window handlevar picker = new FileOpenPicker();
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd);
picker.FileTypeFilter.Add(".txt");
varfile = await picker.PickSingleFileAsync();
Threading Migration
UWP Pattern
WinUI 3 Equivalent
CoreDispatcher.RunAsync(priority, callback)
DispatcherQueue.TryEnqueue(priority, callback)
Dispatcher.HasThreadAccess
DispatcherQueue.HasThreadAccess
CoreDispatcher.ProcessEvents()
No equivalent — restructure async code
CoreWindow.GetForCurrentThread()
Not available — use DispatcherQueue.GetForCurrentThread()
Key difference: UWP uses ASTA (Application STA) with built-in reentrancy blocking. WinUI 3 uses standard STA without this protection. Watch for reentrancy issues when async code pumps messages.
All GetForCurrentView() patterns are unavailable in WinUI 3 desktop apps:
UWP API
WinUI 3 Replacement
UIViewSettings.GetForCurrentView()
Use AppWindow properties
ApplicationView.GetForCurrentView()
AppWindow.GetFromWindowId(windowId)
DisplayInformation.GetForCurrentView()
Win32 GetDpiForWindow() or XamlRoot.RasterizationScale
CoreApplication.GetCurrentView()
Not available — track windows manually
SystemNavigationManager.GetForCurrentView()
Handle back navigation in NavigationView directly
Testing Migration
UWP unit test projects do not work with WinUI 3. You must migrate to the WinUI 3 test project templates.
UWP
WinUI 3
Unit Test App (Universal Windows)
Unit Test App (WinUI in Desktop)
Standard MSTest project with UWP types
Must use WinUI test app for Xaml runtime
[TestMethod] for all tests
[TestMethod] for logic, [UITestMethod] for XAML/UI tests
Class Library (Universal Windows)
Class Library (WinUI in Desktop)
// ✅ WinUI 3 unit test — use [UITestMethod] for any XAML interaction
[UITestMethod]
publicvoidTestMyControl()
{
var control = new MyLibrary.MyUserControl();
Assert.AreEqual(expected, control.MyProperty);
}
Key: The [UITestMethod] attribute tells the test runner to execute the test on the XAML UI thread, which is required for instantiating any Microsoft.UI.Xaml type.
Migration Checklist
Replace all Windows.UI.Xaml.* using directives with Microsoft.UI.Xaml.*
Replace Windows.UI.Colors with Microsoft.UI.Colors
Replace CoreDispatcher.RunAsync with DispatcherQueue.TryEnqueue
Replace Window.Current with App.MainWindow static property
Add XamlRoot to all ContentDialog instances
Initialize all pickers with InitializeWithWindow.Initialize(picker, hwnd)
Replace MessageDialog with ContentDialog
Replace ApplicationView/CoreWindow with AppWindow
Replace CoreApplicationViewTitleBar with AppWindowTitleBar
Replace all GetForCurrentView() calls with AppWindow equivalents
Update interop for Share and Print managers
Replace IBackgroundTask with AppLifecycle activation
Update project file: TFM to net10.0-windows10.0.22621.0, add <UseWinUI>true</UseWinUI>
Migrate unit tests to Unit Test App (WinUI in Desktop) project; use [UITestMethod] for XAML tests
Test both packaged and unpackaged configurations
Files1
1 files · 1.0 KB
Select a file to preview
Overall Score
88/100
Grade
A
Excellent
Safety
92
Quality
85
Clarity
90
Completeness
82
Summary
This skill provides a comprehensive UWP-to-WinUI 3 migration reference guide with before/after code snippets. It maps legacy UWP APIs to Windows App SDK equivalents, covering namespace changes, threading, windowing, dialogs, pickers, background tasks, and documents the most common Copilot-generated code mistakes (ContentDialog without XamlRoot, MessageDialog usage, CoreDispatcher vs. DispatcherQueue).
Phrases that MCP clients use to match this skill to user intent.
migrate uwp to winui3winui3 api mappingfix copilot winui3 codewinui3 namespace changescontentdialog xamlroot errordispatcher migration winui3
Use Cases
Migrating an existing UWP desktop app to WinUI 3
Verifying that AI-generated WinUI 3 code uses correct modern APIs
Debugging WinUI 3 code that throws runtime errors like InvalidOperationException on dialogs
Updating test projects from UWP test framework to WinUI 3 test framework
Fixing namespace compatibility issues when porting UWP code to Windows App SDK
Quality Notes
Skill is well-structured with clear sections (Namespace Changes, Top 3 Mistakes, Windowing, Threading, etc.) that address the most common pain points in UWP migration
Excellent use of before/after code snippets with ❌ and ✅ markers to illustrate common mistakes versus correct patterns
Includes specific error types (InvalidOperationException) so developers can recognize when they've hit a known issue
Comprehensive migration checklist at the end provides actionable steps for methodical migration
Covers both packaged and unpackaged app scenarios for settings migration
Threading section explains the key architectural difference between UWP's ASTA and WinUI 3's STA to help developers understand reentrance risk
Testing migration section explicitly addresses the common error of trying to use UWP test projects with WinUI 3, with clear guidance to [UITestMethod]
Reference tables (Window Management, Threading, GetForCurrentView replacements) make API mapping quick to scan
Includes Win32 interop patterns (window handle initialization for pickers) which are often missed in generated code
Model: claude-haiku-4-5-20251001Analyzed: Jun 26, 2026
Reviews
Add this skill to your library to leave a review.
No reviews yet
Be the first to share your experience.
Use github/winui3-migration-guide in your dev environment — a Developer account adds skills to your library and syncs them via the SkillRepo CLI.