將 WPF 應用程式遷移到 WinUI 3

WPF 應用程式運行於 .NET 上,但使用 Windows Presentation Foundation XAML 堆疊。 WinUI 3 是現代的替代品。 AI 遷移的核心挑戰在於 WPF 使用 System.Windows.* 命名空間,而 WinUI 3 使用 Microsoft.UI.Xaml.*,許多控制項與視窗 API 需要針對性替換,而非簡單的搜尋替換。

安裝 WPF 遷移技能

gh copilot plugin install winui@awesome-copilot

API 替換表

Namespaces

WPF WinUI 3
System.Windows.* Microsoft.UI.Xaml.*
System.Windows.Controls.* Microsoft.UI.Xaml.Controls.*
System.Windows.Media.* Microsoft.UI.Xaml.Media.*
System.Windows.Data.* Microsoft.UI.Xaml.Data.*
System.Windows.Input.* Microsoft.UI.Input.*

控制項

WPF WinUI 3 註釋
Window Microsoft.UI.Xaml.Window 不同的 API 表面
Grid、StackPanel、Canvas 未更改 相同名稱
TextBox、Button、CheckBox 未更改 名稱不變,採用 WinUI 樣式
ListBox / ListView ListView 新程式碼請使用 ItemsView
DataGrid DataGrid (社群工具包) 加上 CommunityToolkit.WinUI.Controls.DataGrid
TabControl TabView 不同的 API
Menu / MenuItem MenuBar / MenuBarItem
ToolBar CommandBar
RichTextBox RichEditBox
WebBrowser WebView2 不同的 API,非同步

線程

WPF WinUI 3
Dispatcher.Invoke(...) DispatcherQueue.TryEnqueue(...)
Dispatcher.BeginInvoke(...) DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, ...)
Application.Current.Dispatcher this.DispatcherQueue

視窗與 DPI

WPF WinUI 3
Window.WindowState AppWindow.Presenter (用法 OverlappedPresenter)
SystemParameters.WorkArea DisplayArea.GetFromWindowId(...)
PresentationSource.FromVisual() WinRT.Interop.WindowNative.GetWindowHandle(window)

數據系結

WPF WinUI 3
INotifyPropertyChanged 未更改
ObservableCollection<T> 未更改
{Binding} {x:Bind} 優先(編譯時)
DependencyProperty 未更改
IValueConverter 未更改

資源與風格

WPF WinUI 3
ResourceDictionary 未更改
StaticResource 未更改
DynamicResource {ThemeResource} 用於系統色彩
SystemColors.WindowBrush {ThemeResource SystemFillColorSolidNeutralBrush}

啟動提示

I'm migrating a WPF app to WinUI 3 using the Windows App SDK.

Apply these substitutions:
- System.Windows.* → Microsoft.UI.Xaml.*
- Dispatcher.Invoke / BeginInvoke → DispatcherQueue.TryEnqueue
- Window.WindowState → AppWindow with OverlappedPresenter
- PresentationSource → WinRT.Interop.WindowNative.GetWindowHandle
- DynamicResource for system colors → ThemeResource
- {Binding} → {x:Bind} where possible (compile-time binding)
- ListBox → ListView or ItemsView
- TabControl → TabView
- WebBrowser → WebView2
- DataGrid → CommunityToolkit.WinUI.Controls.DataGrid

Do not use any System.Windows.* namespaces in new code.
Do not use Dispatcher.Invoke — use DispatcherQueue.TryEnqueue.
Flag APIs without a direct WinUI 3 equivalent rather than guessing.

專案檔案變更

<!-- Before (WPF) -->
<TargetFramework>net10.0-windows</TargetFramework>
<UseWPF>true</UseWPF>

<!-- After (WinUI 3) -->
<TargetFramework>net10.0-windows10.0.19041.0</TargetFramework>
<WindowsSdkPackageVersion>10.0.19041.31</WindowsSdkPackageVersion>
dotnet add package Microsoft.WindowsAppSDK

不直接遷移的 API

請告訴客服標記這些,而不是亂猜:

  • WPF Adorner 層 — WinUI 3 中沒有對應的層
  • WPF FlowDocument / DocumentViewer — 可編輯內容時使用 RichEditBox;無瀏覽器對應
  • WPF Viewport3D — 使用 Win2D 或 DirectX 互操作
  • 空域 / HWND 裝載 — 使用 SwapChainPanel 或 Win32 互通模式