首页/前端开发/winui3-migration-guide
W

winui3-migration-guide

by @githubv1.0.0
0.0(0)

'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 t

WinUI 3Windows App ModernizationUWP MigrationXAML UI DevelopmentDesktop ApplicationGitHub
安装方式
npx skills add github/awesome-copilot --skill winui3-migration-guide
compare_arrows

Before / After 效果对比

0

description 文档


name: winui3-migration-guide description: '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

forum用户评价 (0)

发表评价

效果
易用性
文档
兼容性

暂无评价,来写第一条吧

统计数据

安装量4.0K
评分0.0 / 5.0
版本1.0.0
更新日期2026年3月16日
对比案例0 组

用户评分

0.0(0)
5
0%
4
0%
3
0%
2
0%
1
0%

为此 Skill 评分

0.0

兼容平台

🔧Claude Code

时间线

创建2026年3月16日
最后更新2026年3月16日