SuperAPI AI 工具集

winui-wpf-migration

编程与开发

查看项目

更新于 10-16 10:35

技能介绍

用途

该技能用于把现有 WPF 应用迁移或移植到 WinUI 3,提供从准备、审计、改写、替换到验证的分步流程,并列出 WPF 与 WinUI 3 在命名空间、控件、线程、图像和资源上的对应关系。

前置条件与准备

使用 WinApp CLI 0.7+ 的前置条件以及 winui-dev-workflow 中的按应用分析器设置。常规 SDK 路径需要 .NET 8.0.100 或更高版本,以及目标 TFM 所需的 SDK;Native AOT 还需要 MSVC/Desktop C++ 工具。缺失前置条件的处理方式参见 winui-dev-workflow。

迁移流程

  1. 审计 WPF 源码:在编写代码前,清点 WPF 专属 API。使用 PowerShell 命令查找所有 System.Windows. 命名空间的使用,并列出所用 WPF 控件、自定义 MVVM 框架、图像 API、线程模式和 Win32 互操作。
  2. 创建 WinUI 3 项目并对齐命名空间:使用 winapp new 命令创建项目(模板 winui-mvvm),立即在 .csproj 中设置 <RootNamespace> 与 WPF 命名空间一致,并更新 App.xaml、MainWindow.xaml 及其 code-behind 中的 x:Class。按 winui-dev-workflow 添加分析器并构建验证。之后从 WinUI 项目目录(而非旧 WPF 项目或机器 SDK)恢复项目并检查引用,使用 winapp find-api 查询 DispatcherQueue、成员、属性及控件信息,使用 winapp find-ui 获取用法示例。
  3. 替换命名空间:System.Windows → Microsoft.UI.Xaml;System.Windows.Controls → Microsoft.UI.Xaml.Controls;System.Windows.Media → Microsoft.UI.Xaml.Media;System.Windows.Input → Microsoft.UI.Xaml.Input;System.Windows.Data → Microsoft.UI.Xaml.Data;System.Windows.Threading.Dispatcher → Microsoft.UI.Dispatching.DispatcherQueue;PresentationCore / PresentationFramework 完全移除。
  4. 替换控件:DataGrid → 带 Grid 列标题的 ListView;WrapPanel → ItemsRepeater + UniformGridLayout;TabControl → TabView;StatusBar → 底部 Grid 行加 TextBlock;Menu / MenuItem → MenuBar / MenuBarItem / MenuFlyoutItem;ToolBar → CommandBar;自定义 Expander → 内置 Expander。
  5. 替换线程:WPF 的 Application.Current.Dispatcher.Invoke 改为 WinUI 3 的 dispatcherQueue.TryEnqueue,通过 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>,它会静默破坏构建。若存在大量图像代码,应尽早迁移。
  7. 替换 MVVM 框架:删除自定义 ObservableObject/RelayCommand/DelegateCommand,使用 CommunityToolkit.Mvvm。将 INotifyPropertyChanged 基类改为 ObservableObject 加上 [ObservableProperty] 分部属性(修复 MVVMTK0045,不要保留字段);自定义 RelayCommand 改为 [RelayCommand] 特性;已知类型优先使用 {x:Bind},保留运行时 {Binding}/DisplayMemberPath 之处按需处理;DynamicResource → {ThemeResource}。绑定模式、x:DataType 和 AOT 安全运行时绑定详见 winui-packaging 的 references/sourcegen-patterns.md。
  8. 替换资源:.resx → .resw(复制并重命名到 Strings\en-us\);{x:Static} → x:Uid 用于本地化字符串;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。
  • 将迁移拆分为文件级任务,而不是一次性大规模重写。

迁移后验证

使用 PowerShell 检查剩余 WPF 引用(应无结果);验证 Test-Path "Package.appxmanifest" 为 True;使用 dotnet build 构建(分析器在安装后参与);使用 winapp run 运行迁移后的应用。UI 验证参见 winui-ui-testing,崩溃诊断参见 winui-dev-workflow。如需 AOT,还应通过工作流的 AOT 路径测试发布产物;上述运行即使 Release 也是 JIT。

适用场景与限制

适用于由 WPF 向 WinUI 3 迁移的桌面应用改造场景,涉及命名空间、控件、线程、图像、MVVM 和资源的系统性替换。限制包括:必须满足 .NET 8.0.100 及目标 TFM SDK 要求,Native AOT 额外需要 MSVC/Desktop C++ 工具;图像方面存在无法绕过的架构不兼容;不得使用 UseWPF。其他未在资料中说明的平台、收费或效果信息暂未提供。