mcpField
W
winui-wpf-migration

winui-wpf-migration

github.com/microsoft开发490144 次安装3 周前更新
代码仓库

关于 winui-wpf-migration

winui-wpf-migration 是指导将 WPF 应用迁移到 WinUI 3 的技能,面向执行 Windows 桌面应用迁移的开发者。内容按迁移步骤覆盖 API、控件、线程、图像处理和 MVVM 替换,并包含迁移后验证。

主要功能

  1. 01盘点 WPF 专用 API
  2. 02指导 WinUI 3 项目初始化
  3. 03映射命名空间与控件
  4. 04迁移线程和图像处理
  5. 05替换 MVVM 与资源
  6. 06提供迁移后验证步骤

适用场景

  1. 01制定 WPF 应用迁移计划
  2. 02替换不兼容的 WPF API
  3. 03逐步迁移控件和 MVVM 代码
  4. 04检查迁移后的构建与打包

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/microsoft/win-dev-skills --skill winui-wpf-migration

安装后在 Claude Code 中输入/winui-wpf-migration确认已加载。

详细介绍

迁移流程

使用 winui-dev-workflow 中的 WinApp CLI 0.7+ 前置条件和针对每个应用的分析器设置。常规 SDK 路径需要 .NET 8.0.100 或更高版本,以及目标 TFM 所需的 SDK;Native AOT 还需要 MSVC/Desktop C++ 工具。按照该文档中的说明处理缺失的前置条件。

步骤 1:审查 WPF 源代码

编写代码前,先盘点 WPF 专用 API:

# Find all WPF namespace usage
Select-String -Path (Get-ChildItem -Recurse -Filter "*.cs" | Where-Object { $_.FullName -notlike "*\obj\*" }) -Pattern "System\.Windows\." | Select-Object -Property Filename, LineNumber, Line

清单:使用的 WPF 控件、自定义 MVVM 框架、成像 API、线程处理模式、Win32 互操作。

步骤 2:创建 WinUI 3 项目并对齐命名空间
winapp new --name <AppName> --template winui-mvvm --template-version latest --use-defaults

立即在 .csproj 中设置 <RootNamespace>,使其与 WPF 命名空间一致。更新 App.xaml、MainWindow.xaml 及其代码隐藏文件中的 x:Class。按照 winui-dev-workflow 添加分析器。在移植任何代码前先构建验证。

实现 API 替换前,在 WinUI 项目目录中还原应用项目,并检查其实际引用;不要从旧 WPF 项目或计算机 SDK 检查:

winapp find-api DispatcherQueue --json --project-dir .
winapp find-api members DispatcherQueue --filter TryEnqueue --json --project-dir .
winapp find-api check-property ListView ItemsSource SelectionMode --json --project-dir .

使用 winapp find-ui "<intent>" 获取用法示例;项目选择和批量 API 检查请参阅 winui-design。

步骤 3:替换命名空间
WPFWinUI 3
System.WindowsMicrosoft.UI.Xaml
System.Windows.ControlsMicrosoft.UI.Xaml.Controls
System.Windows.MediaMicrosoft.UI.Xaml.Media
System.Windows.InputMicrosoft.UI.Xaml.Input
System.Windows.DataMicrosoft.UI.Xaml.Data
System.Windows.Threading.DispatcherMicrosoft.UI.Dispatching.DispatcherQueue
PresentationCore / PresentationFramework完全移除
步骤 4:替换控件
WPF 控件WinUI 3 对应项
DataGrid带 Grid 列标题的 ListView
WrapPanelItemsRepeater + UniformGridLayout
TabControlTabView
StatusBar底部带 TextBlock 元素的 Grid 行
Menu / MenuItemMenuBar / MenuBarItem / MenuFlyoutItem
ToolBarCommandBar
Expander(自定义)Expander(内置)
步骤 5:替换线程处理
// WPF
Application.Current.Dispatcher.Invoke(() => { /* UI work */ });

// WinUI 3
dispatcherQueue.TryEnqueue(() => { /* UI work */ });

通过 DispatcherQueue.GetForCurrentThread() 获取。WinUI 3 中没有 Application.Current.Dispatcher。

步骤 6:替换成像功能

重要: PresentationCore.dll 和 System.Windows.Media.Imaging 会导致 WinUI XAML 编译器崩溃。这是架构不兼容,无法规避。

  • 在迁移开始时移除所有 System.Windows.Media.Imaging 引用
  • 替换为 Windows.Graphics.Imaging(WinRT)或 Microsoft.UI.Xaml.Media.Imaging.BitmapImage
  • 不要添加 <UseWPF>true</UseWPF> —— 这会悄悄破坏构建
  • 如果存在大量成像代码,请尽早迁移(第 2 步,而不是第 7 步)
步骤 7:替换 MVVM 框架

删除自定义的 ObservableObject/RelayCommand/DelegateCommand。使用 CommunityToolkit.Mvvm:

  • INotifyPropertyChanged 基类 → 使用 [ObservableProperty] partial 属性的 ObservableObject(修复 MVVMTK0045;不要保留字段)
  • 自定义 RelayCommand → [RelayCommand] 特性
  • 已知类型优先使用 {x:Bind};必要时保留运行时 {Binding}/DisplayMemberPath。有关绑定模式、x:DataType 和适用于 AOT 的运行时绑定,请参阅 winui-packaging 的 references/sourcegen-patterns.md。
  • DynamicResource → {ThemeResource}
步骤 8:替换资源
  • .resx → .resw(复制并重命名到 Strings\en-us\)
  • 本地化字符串使用 x:Uid 替换 {x:Static}
  • Properties.Resources.Key → ResourceLoader.GetString("Key")
关键规则
  • ❌ 绝不引用 PresentationCore、PresentationFramework 或 System.Windows.Controls 程序集
  • ❌ 绝不添加 <UseWPF>true</UseWPF>
  • 默认保持打包模式;若要进行非打包实验,请参阅 winui-dev-workflow 的关键规则。
  • ❌ 绝不删除 Package.appxmanifest
  • ❌ 绝不覆盖 App.xaml / App.xaml.cs——将 WPF 代码合并到 WinUI 3 样板代码中
  • ✅ 使用项目模式的 winapp run 启动,不要直接运行 .exe。
  • ✅ 将迁移拆分为按文件执行的任务——不要一次性大规模重写
迁移后验证
# Check for remaining WPF references (should return nothing)
Select-String -Path (Get-ChildItem -Recurse -Filter "*.cs" | Where-Object { $_.FullName -notlike "*\obj\*" }) -Pattern "System\.Windows\."

# Verify packaging preserved
Test-Path "Package.appxmanifest"  # should be True

# Build (the analyzer participates when installed)
dotnet build .\MyApp.csproj -p:Platform=x64

# Run the migrated app
winapp run .\MyApp.csproj --detach --json

UI 验证请参阅 winui-ui-testing;崩溃诊断请参阅 winui-dev-workflow。如果计划使用 AOT,还要通过工作流的 AOT 路径测试发布产物;上面的运行使用的是 JIT,即使在 Release 模式下也是如此。

评论

支持 Markdown