Skill Store 33

Winui3 Migration Guide

UWP-to-WinUI 3 migration reference.

by github · MIT

The skill

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.

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 3
var dialog = new ContentDialog
{
    Title = "Error",
    Content = "Something went wrong.",
    CloseButtonText = "OK"
};
await dialog.ShowAsync();
// ✅ CORRECT — Set XamlRoot before showing
var 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 desktop
var dialog = new Windows.UI.Popups.MessageDialog("Are you sure?", "Confirm");
await dialog.ShowAsync();
// ✅ CORRECT — Use ContentDialog
var 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 3
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
    StatusText.Text = "Done";
});
// ✅ CORRECT — Use DispatcherQueue
DispatcherQueue.TryEnqueue(() =>
{
    StatusText.Text = "Done";
});

// With priority:
DispatcherQueue.TryEnqueue(DispatcherQueuePriority.High, () =>
{
    ProgressBar.Value = 100;
});

Windowing Migration

Window Reference

// ❌ WRONG — Window.Current does not exist in WinUI 3
var currentWindow = Window.Current;
// ✅ CORRECT — Use a static property in App
public partial class App : Application
{
    public static Window MainWindow { get; private set; }

    protected override void OnLaunched(LaunchActivatedEventArgs args)
    {
        MainWindow = new MainWindow();
        MainWindow.Activate();
    }
}
// Access anywhere: App.MainWindow

Window Management

UWP API WinUI 3 API
ApplicationView.TryResizeView() AppWindow.Resize()
AppWindow.TryCreateAsync() AppWindow.Create()
AppWindow.TryShowAsync() AppWindow.Show()
AppWindow.TryConsolidateAsync() AppWindow.Destroy()
AppWindow.RequestMoveXxx() AppWindow.Move()
AppWindow.GetPlacement() AppWindow.Position property
AppWindow.RequestPresentation() AppWindow.SetPresenter()

Title Bar

UWP API WinUI 3 API
CoreApplicationViewTitleBar AppWindowTitleBar
CoreApplicationView.TitleBar.ExtendViewIntoTitleBar AppWindow.TitleBar.ExtendsContentIntoTitleBar

Dialogs and Pickers Migration

File/Folder Pickers

// ❌ WRONG — UWP style, no window handle
var picker = new FileOpenPicker();
picker.FileTypeFilter.Add(".txt");
var file = await picker.PickSingleFileAsync();
// ✅ CORRECT — Initialize with window handle
var picker = new FileOpenPicker();
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd);
picker.FileTypeFilter.Add(".txt");
var file = 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.


Background Tasks Migration

// ❌ WRONG — UWP IBackgroundTask
public sealed class MyTask : IBackgroundTask
{
    public void Run(IBackgroundTaskInstance taskInstance) { }
}
// ✅ CORRECT — Windows App SDK AppLifecycle
using Microsoft.Windows.AppLifecycle;

// Register for activation
var args = AppInstance.GetCurrent().GetActivatedEventArgs();
if (args.Kind == ExtendedActivationKind.AppNotification)
{
    // Handle background activation
}

App Settings Migration

Scenario Packaged App Unpackaged App
Simple settings ApplicationData.Current.LocalSettings JSON file in LocalApplicationData
Local file storage ApplicationData.Current.LocalFolder Environment.GetFolderPath(SpecialFolder.LocalApplicationData)

GetForCurrentView() Replacements

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]
public void TestMyControl()
{
    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

  1. [ ] Replace all Windows.UI.Xaml.* using directives with Microsoft.UI.Xaml.*
  2. [ ] Replace Windows.UI.Colors with Microsoft.UI.Colors
  3. [ ] Replace CoreDispatcher.RunAsync with DispatcherQueue.TryEnqueue
  4. [ ] Replace Window.Current with App.MainWindow static property
  5. [ ] Add XamlRoot to all ContentDialog instances
  6. [ ] Initialize all pickers with InitializeWithWindow.Initialize(picker, hwnd)
  7. [ ] Replace MessageDialog with ContentDialog
  8. [ ] Replace ApplicationView/CoreWindow with AppWindow
  9. [ ] Replace CoreApplicationViewTitleBar with AppWindowTitleBar
  10. [ ] Replace all GetForCurrentView() calls with AppWindow equivalents
  11. [ ] Update interop for Share and Print managers
  12. [ ] Replace IBackgroundTask with AppLifecycle activation
  13. [ ] Update project file: TFM to net10.0-windows10.0.22621.0, add <UseWinUI>true</UseWinUI>
  14. [ ] Migrate unit tests to Unit Test App (WinUI in Desktop) project; use [UITestMethod] for XAML tests
  15. [ ] Test both packaged and unpackaged configurations

Use this skill

Connect your agent to the Skill Store MCP server and ask for it by ref: github/winui3-migration-guide-35969303548.

Download SKILL.md · Markdown version

Details

Publisher
github
Category
Software Development › Frontend & UI
License
MIT
Updated
2026-10-16

References

More from github