winui-wpf-migration について
winui-wpf-migrationは、WPFアプリをWinUI 3へ移行する開発者向けのスキルです。API、コントロール、スレッド処理、画像処理、MVVMの置き換えを段階的に案内し、移行後の検証方法も示します。
主な機能
- 01WPF固有APIの洗い出し
- 02WinUI 3プロジェクトの準備
- 03名前空間とコントロールの対応付け
- 04スレッド処理と画像処理の移行
- 05MVVMとリソースの置き換え
- 06移行後の検証手順
活用シーン
- 01WPFアプリの移行計画
- 02互換性のないWPF APIの置き換え
- 03コントロールとMVVMコードの段階的な移行
- 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/デスクトップ 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 の置き換えを実装する前に、古い WPF プロジェクトやマシンの SDK ではなく、WinUI プロジェクトのディレクトリからアプリプロジェクトを復元し、正確な参照を確認します。
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:名前空間を置き換える
| WPF | WinUI 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:コントロールを置き換える
| WPF コントロール | WinUI 3 の同等機能 |
|---|---|
DataGrid | グリッド列ヘッダーを備えた ListView |
WrapPanel | ItemsRepeater + UniformGridLayout |
TabControl | TabView |
StatusBar | 下部に TextBlock 要素を配置した Grid の行 |
Menu / MenuItem | MenuBar / MenuBarItem / MenuFlyoutItem |
ToolBar | CommandBar |
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>は追加しないでください。ビルドが気づかないうちに破損します- 画像処理コードが大量にある場合は、早い段階(ステップ 7 ではなくステップ 2)で移行します
ステップ 7:MVVM フレームワークを置き換える
カスタムの ObservableObject/RelayCommand/DelegateCommand を削除します。CommunityToolkit.Mvvm を使用します。
INotifyPropertyChangedの基底クラス →[ObservableProperty]を使ったObservableObjectの partial プロパティ(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: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 のボイラープレートにマージしてください - ✅ .exe を直接起動するのではなく、プロジェクトモードの
winapp runで起動してください。 - ✅ 移行はファイル単位のタスクに分割してください。一度に大規模な書き換えを行わないでください
移行後の検証
# 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 パスを使って公開済みの成果物もテストしてください。上記の実行は Release でも JIT です。