跳到主要内容
知仓学习社ZHICANG

winui3-migration-guide

UWP-to-WinUI 3 migration reference. Maps legacy UWP APIs to correct Windows App SDK equivalents with before/after code snippets. Covers namespace ch…

不碰外部(只输出文字)无严重或高危命中github/awesome-copilot

它会碰到什么

扫了多少1 个文本文件,9 KB
它会碰到什么不碰外部(只输出文字)
命中总数0 处
命中统计严重 0 · 高 0 · 中 0 · 低 0

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

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

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。