dotnet-wpf-migration について
dotnet-wpf-migrationは、Windowsデスクトップアプリを最新化するチーム向けの移行ガイドスキルです。最新の.NETへのアップグレードや、WPF、WinUI 3、Uno Platform間の移行を扱い、プロジェクトの制約に応じた経路を示します。
主な機能
- 01WPF .NET Frameworkから.NET 8+へ移行
- 02WinForms .NET Frameworkから.NET 8+へ移行
- 03WPFからWinUI 3への移行
- 04WPFからUno Platformへの移行
- 05UWPの移行経路
- 06移行工数とリスクの比較
活用シーン
- 01UIを維持してWPFアプリを更新
- 02WinFormsアプリのランタイムを最新化
- 03WPFビューをWinUI 3向けに書き換え
- 04WPFコードベースをクロスプラットフォーム化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ wshaddix/ dotnet-skills --skill dotnet-wpf-migrationインストール後、Claude Code で/dotnet-wpf-migrationを入力して読み込まれたか確認します。
詳細
dotnet-wpf-migration
Windows デスクトップアプリケーション向けの、状況に応じた移行ガイダンスです。WPF .NET Framework から .NET 8 以降への移行、WPF から WinUI 3 への移行(Windows 限定のモダナイズ)、WPF から Uno Platform への移行(クロスプラットフォーム)、WinForms .NET Framework から .NET 8 以降への移行、UWP から WinUI 3 への移行、UWP から Uno Platform への移行(相互参照)、およびプロジェクトの制約に基づいて適切な移行先を選ぶための判断マトリックスを扱います。
バージョンの前提: .NET 8.0 以降をベースラインとします(現行の LTS)。自動移行には dotnet-upgrade-assistant を使用します。該当する場合は、.NET 9 の機能を明記します。
対象範囲の境界: このスキルでは、デスクトップフレームワーク間、および .NET Framework から最新の .NET への移行パスを扱います。各フレームワークのパターン(WPF のモダンな開発、WinUI、WinForms のモダンな開発)は、それぞれのフレームワーク用スキルで扱います。フレームワーク選択の判断ツリーは [skill:dotnet-ui-chooser] で扱います。
対象外: WPF .NET 8 以降の開発パターンについては、[skill:dotnet-wpf-modern] を参照してください。WinUI 3 の開発パターンについては、[skill:dotnet-winui] を参照してください。WinForms .NET 8 以降の開発パターンについては、[skill:dotnet-winforms-basics] を参照してください。Uno Platform の開発パターンについては、[skill:dotnet-uno-platform] を参照してください。フレームワーク選択の判断ツリーについては、[skill:dotnet-ui-chooser] を参照してください。デスクトップのテストについては、[skill:dotnet-ui-testing-core] を参照してください。
相互参照:WPF .NET 8 以降のパターンについては [skill:dotnet-wpf-modern]、WinUI 3 のパターンについては [skill:dotnet-winui]、WinForms .NET 8 以降のパターンについては [skill:dotnet-winforms-basics]、Uno Platform のパターンについては [skill:dotnet-uno-platform]、フレームワーク選択については [skill:dotnet-ui-chooser]、デスクトップのテストについては [skill:dotnet-ui-testing-core] を参照してください。
移行パスの概要
現在のフレームワークと移行先の目標に基づいて、移行パスを選択してください。各パスでは、作業量、リスク、機能向上の度合いが異なります。
| 現在の環境 | 移行先 | 作業量 | リスク | 選択する状況 |
|---|---|---|---|---|
| WPF .NET Framework | WPF .NET 8+ | 低~中 | 低 | 既存の UI を維持しながらランタイムを最新化する |
| WPF .NET Framework | WinUI 3 | 高 | 中 | 最新の Windows UI、タッチ/ペン、Fluent が必要 |
| WPF .NET Framework | Uno Platform | 高 | 中~高 | クロスプラットフォーム対応が必要 |
| WinForms .NET Framework | WinForms .NET 8+ | 低 | 低 | 既存の UI を維持しながらランタイムを最新化する |
| UWP | WinUI 3 | 中 | 中 | Windows 限定を維持しながらランタイムを最新化する |
| UWP | Uno Platform | 中~高 | 中 | UWP からのクロスプラットフォーム対応が必要 |
WPF .NET Framework から .NET 8 以降へ
最もリスクの低い移行パスです。既存の XAML とコードビハインドをそのまま維持しながら、パフォーマンスの向上、DI のサポート、サイドバイサイド展開が可能な最新の .NET に移行できます。
dotnet-upgrade-assistant を使用する
.NET Upgrade Assistant は、移行の大部分を自動化します。
# Install the upgrade assistant
dotnet tool install -g upgrade-assistant
# Analyze the project first (non-destructive)
upgrade-assistant analyze MyWpfApp.sln
# Upgrade the project
upgrade-assistant upgrade MyWpfApp.sln
Upgrade Assistant が対応する項目:
.csprojを従来の形式から SDK 形式に変換packages.configからPackageReferenceへの移行- TFM を
net8.0-windowsに変更 AssemblyInfo.csのプロパティを.csprojに移動- 一般的な API の置き換えと名前空間の更新
手作業が必要な項目:
App.configの設定をappsettings.jsonまたは Host ビルダーの構成に移行Settings.settings/My.Settings(VB.NET)の移行- サードパーティ製コントロールライブラリの更新(ベンダーによる .NET 8 への対応状況を確認)
- WCF クライアント参照(
CoreWCFを使用するか、gRPC/REST に移行) - COM 相互運用の調整(
System.Runtime.InteropServicesの構文の違い) - カスタム MSBuild ターゲットとビルドスクリプト
API の互換性
ほとんどの WPF API は、.NET Framework と .NET 8+ で同一です。主な違いは次のとおりです。
| 領域 | .NET Framework | .NET 8+ | 対応 |
|---|---|---|---|
| クリップボード | Clipboard.SetText() | 同じ API | 変更なし |
| 印刷 | PrintDialog、PrintVisual | 同じ API | 変更なし |
| BitmapEffect | 非推奨(ソフトウェアレンダリング) | 削除 | Effect / ShaderEffect を使用 |
DrawingContext.PushEffect | 利用可能 | 削除 | ShaderEffect を使用 |
| XPS ドキュメント | System.Windows.Xps | NuGet パッケージが必要 | System.Windows.Xps の PackageReference を追加 |
| 音声合成 | System.Speech | NuGet パッケージが必要 | System.Speech の PackageReference を追加 |
NuGet パッケージの更新
移行後、NuGet パッケージを .NET 8 対応バージョンに更新します。
# List outdated packages
dotnet list package --outdated
# Update packages (one at a time for safer migration)
dotnet add package Newtonsoft.Json --version 13.*
dotnet add package MaterialDesignThemes --version 5.*
一般的なパッケージの置き換え:
Unityコンテナー ->Microsoft.Extensions.DependencyInjection(組み込み)Autofac-> 最新版に更新(.NET 8 に対応)log4net/NLog-> Serilog または NLog プロバイダーとともにMicrosoft.Extensions.Loggingの利用を検討EntityFramework(EF6) ->Microsoft.EntityFrameworkCore8.x
破壊的変更のチェックリスト
- 高 DPI の既定の動作が変更されました。 .NET 8 WPF は、既定で
PerMonitorV2DPI 認識を有効にします(.NET Framework のようなSystemAwareではありません)。 - Null 許容参照型。 新しいプロジェクトでは NRT が有効になります。既存のコードで警告が発生する場合があります。まず
<Nullable>disable</Nullable>で警告を抑制し、その後、段階的に修正してください。 - 暗黙的な using。 新しい SDK スタイルのプロジェクトでは、暗黙的な using が有効になります。既存の
usingステートメントと競合する場合があります。必要に応じて<ImplicitUsings>disable</ImplicitUsings>で無効にしてください。 - アセンブリの読み込み。 アセンブリの分離には、
AppDomainの代わりにAssemblyLoadContextを使用します。AppDomain.CreateDomainを使用するプラグインアーキテクチャは、再設計が必要です。 - ランタイムの動作。 .NET 8 の GC は、Gen0/Gen1 コレクションをより積極的に実行します。ファイナライザーに依存するコードの動作が異なる場合があります。
移行後の WPF パターン(Host ビルダー、MVVM Toolkit、最新の C#)については、[スキル:dotnet-wpf-modern] を参照してください。
WPF から WinUI 3 へ
Fluent Design、タッチ/ペン入力、Windows 11 との統合(ウィジェット、Mica)、または最新の .NET での UWP スタイル API など、最新の Windows ネイティブ UI が必要な場合に移行します。これは部分的な書き換えです。XAML の概念は引き継げますが、API と名前空間は異なります。
この移行が適している場合
- アプリケーションがWindows 専用であり、今後も Windows 専用である
- 最新のFluent Designコントロール、タッチ/ペンのサポート、または Windows 11 の機能が必要である
- チームがXAML の書き換えに労力をかける意向がある
- アプリケーションが積極的に開発されており、継続的な機能開発が行われている(投資に見合う)
代替案を検討する場合
- クロスプラットフォームが必要な場合 -> 代わりに Uno Platform へ移行します(WinUI XAML サーフェス)
- アプリケーションが保守モードの場合 -> 代わりに WPF .NET 8+ へ移行します(作業量を抑えられます)
- WPF Fluent テーマ(.NET 9+)で十分な場合 ->
ThemeMode = ThemeMode.Systemを指定して WPF .NET 8+ を継続します
XAML の違い
| WPF XAML | WinUI 3 XAML | 備考 |
|---|---|---|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | 同じ URI(ただし、System.Windows ではなく Microsoft.UI.Xaml の型に解決されます) | xmlns の変更はありませんが、実行時の型は異なります |
{Binding Path=Name} | {x:Bind Name, Mode=OneWay} | x:Bind を推奨します(コンパイル済みで、型安全です) |
DataContext バインディング | コードビハインドのプロパティ + x:Bind | x:Bind はコードビハインドを参照します |
Window は System.Windows.Window を継承します | Window は Microsoft.UI.Xaml.Window を継承します | 基底クラスと API が異なります |
UserControl | UserControl(Microsoft.UI.Xaml 名前空間) | 概念は同じですが、名前空間が異なります |
TargetType を指定した Style | 同じ | 同じように機能します |
DataTemplate | x:Bind には x:DataType が必要です | コンパイル済みバインディングに必須です |
ContextMenu | MenuFlyout | コントロールの種類が異なります |
StatusBar | 組み込みの同等機能はありません | カスタムの CommandBar または InfoBar を使用します |
RibbonControl | 組み込みの同等機能はありません | NavigationView + CommandBar を使用します |
移行戦略
- 既存の WPF プロジェクトと並行して、新しい WinUI 3 プロジェクトを作成します
- まず共有ロジックを移行します -- モデル、サービス、ViewModel(MVVM Toolkit を使用している場合は、どちらでも動作します)
- ビューを段階的に移行します -- シンプルなページから始め、次に複雑なページに進みます
- WPF 固有のコントロールを WinUI の同等機能に置き換えます(上の表を参照)
- コンパイル時の安全性を確保するため、データバインディングを
{Binding}から{x:Bind}に更新します - Windows 統合機能(通知、ライフサイクル、ファイルの関連付け)をテストします
- デプロイモデルを選択します -- MSIX(アプリ ID)またはアンパッケージ(xcopy)
WinUI 3 のパターンとプロジェクトのセットアップについては、[skill:dotnet-winui] を参照してください。
WPF から Uno Platform へ
WPF のコードベースをクロスプラットフォームに展開する必要がある場合に移行します。Uno Platform は WinUI の XAML API サーフェスを使用するため、WPF の XAML スキルの一部は引き継げますが、移行には WinUI の XAML パターンへの適応が必要です。
この移行が適している場合
- アプリケーションを複数のプラットフォーム(Windows、macOS、Linux、Web、モバイル)で実行する必要がある
- チームに WinUI XAML サーフェスにも活用できるWPF/XAML の専門知識がある
- クロスプラットフォームへの適応(プラットフォーム固有の動作、レスポンシブなレイアウト)に投資する意思がある
代替案を検討する場合
- Windows 専用の場合 -> WinUI 3 に移行します(よりシンプルで、クロスプラットフォーム対応のオーバーヘッドがありません)
- アプリケーションがメンテナンスモードの場合 -> WPF .NET 8+ に移行します(最も手間が少なくて済みます)
- チームにWeb のスキルがある場合 -> Web 配信には Blazor を検討します
移行方法
Uno Platform は WinUI API サーフェスを使用するため、WPF から Uno Platform への移行は、WPF から WinUI 3 への移行と似ていますが、クロスプラットフォームに関する考慮事項が追加されます。
- 目的のターゲットプラットフォームを指定して、Uno Platform プロジェクトを作成します
- ViewModel とサービスを移行します -- これらはプラットフォームに依存しません
- XAML を WinUI の構文に適応させます(WPF から WinUI への移行と同じ変更です)
- 条件付きコンパイルまたは Uno のプラットフォーム拡張機能を使用して、プラットフォーム固有の機能に対応します
- Windows 専用 API をクロスプラットフォームの代替機能(ファイルダイアログ、通知など)に置き換えます
- 各ターゲットプラットフォームをテストします -- Skia とネイティブのターゲットでは、レンダリングや動作が異なる場合があります
一般的なパターンに対応する Uno Extensions
Uno Extensions は、一般的な WPF パターンに代わるクロスプラットフォームの機能を提供します。
| WPF のパターン | Uno Extensions の代替機能 |
|---|---|
| カスタムナビゲーション | Uno.Extensions.Navigation |
| 手動での DI セットアップ | Uno.Extensions.DependencyInjection(MS DI をラップします) |
appsettings.json の設定 | Uno.Extensions.Configuration |
| 手動での HTTP クライアント | Uno.Extensions.Http(Refit を使用する型付きクライアント) |
| 手動でのシリアル化 | Uno.Extensions.Serialization |
Uno Platform の開発パターンについては、[skill:dotnet-uno-platform] を参照してください。ターゲットごとのデプロイ方法については、[skill:dotnet-uno-targets] を参照してください。
WinForms .NET Framework から .NET 8+
WPF の移行と同様ですが、WinForms はプロジェクト構造がそれほど複雑ではないため、通常はより簡単です。
dotnet-upgrade-assistant を使用する
# Analyze first
upgrade-assistant analyze MyWinFormsApp.sln
# Upgrade
upgrade-assistant upgrade MyWinFormsApp.sln
アップグレードアシスタントが処理する内容:
.csprojを<UseWindowsForms>true</UseWindowsForms>を含む SDK スタイルに変換- TFM を
net8.0-windowsに変更 packages.configをPackageReferenceに変換AssemblyInfo.csをプロジェクトプロパティに移行
手動作業が必要な内容:
App.config/Settings.settingsの移行My.Settings(VB.NET)を最新の構成に移行- サードパーティ製コントロールライブラリの更新(一部の WinForms コントロールは .NET 8 をサポートしていない場合があります)
- Crystal Reports などのレガシーなレポートツール(代替手段を検討してください)
- COM 相互運用の調整
デザイナーの互換性
WinForms デザイナーファイル(.Designer.cs)は通常、問題なく移行できます。.NET 8+ 用の Visual Studio WinForms デザイナーは完全にサポートされています。
既知のデザイナーの問題:
- カスタムデザイナーシリアライザーの更新が必要な場合があります
- 一部のサードパーティ製コントロールは .NET 8 デザイナーで描画されない場合があります
- DPI 非対応のデザイナーモードは .NET 9+ で利用できます(
<ForceDesignerDPIUnaware>true</ForceDesignerDPIUnaware>)
移行後のモダン化
.NET 8+ に移行した後は、最新のパターンを段階的に取り入れることを検討してください:
- 依存関係の注入を追加:Host ビルダーを使用します([skill:dotnet-winforms-basics] を参照)
- 同期呼び出しを置き換え:async/await を使用します
- 高 DPI を有効化:
PerMonitorV2モードを使用します - ダークモードを有効化(.NET 9+ では試験段階です)
WinForms .NET 8+ のパターンについては、[skill:dotnet-winforms-basics] を参照してください。
UWP から WinUI 3 へ
UWP の自然な移行先です。WinUI 3 は同じ XAML API サーフェスを使用しますが、名前空間が変更されています。
名前空間の変更
主な移行作業は、名前空間を Windows.UI.* から Microsoft.UI.* に更新することです:
| UWP の名前空間 | WinUI 3 の名前空間 |
|---|---|
Windows.UI.Xaml | Microsoft.UI.Xaml |
Windows.UI.Xaml.Controls | Microsoft.UI.Xaml.Controls |
Windows.UI.Xaml.Media | Microsoft.UI.Xaml.Media |
Windows.UI.Composition | Microsoft.UI.Composition |
Windows.UI.Text | Microsoft.UI.Text |
そのまま維持するもの: Windows.Storage、Windows.Networking、Windows.Security、Windows.ApplicationModel、Windows.Devices — これらの WinRT API は変更されません。
アプリモデルの違い
| 項目 | UWP | WinUI 3 |
|---|---|---|
| アプリのライフサイクル | CoreApplication + 中断 | Windows App SDK の AppInstance |
| ウィンドウ管理 | Window.Current(シングルトン) | ウィンドウ参照を手動で追跡 |
| ディスパッチャー | CoreDispatcher.RunAsync | DispatcherQueue.TryEnqueue |
| バックグラウンドタスク | 組み込み、パッケージ ID が必要 | MSIX では利用可能、なしの場合は制限あり |
| ファイルアクセス | マニフェストによる広範な機能 | 標準の Win32 ファイルアクセス + StorageFile |
| Store API | Windows.Services.Store | 同じ(引き続き利用可能) |
移行手順
- 新しい WinUI 3 プロジェクトを作成:Windows App SDK テンプレートを使用します
- ソースファイルをコピーし、名前空間を更新します(
Windows.UI.XamlからMicrosoft.UI.Xaml) - 非推奨の API を置き換えます(
Window.Currentを手動追跡に、CoreDispatcherをDispatcherQueueに置き換えます) - MSIX マニフェストを更新します(UWP 形式から Windows App SDK 形式へ)
- 機能を移行します — 機能宣言を確認して更新してください
- NuGet パッケージを更新し、Windows App SDK 対応バージョンにします
- Windows との統合をテストします — 通知、バックグラウンドタスク、ファイルの関連付けの動作が異なる場合があります
UWP の .NET 9 プレビュー移行パス: Microsoft は、プレビューとして .NET 9 での UWP サポートを発表しました。WinUI 3 への完全な移行にコストがかかりすぎる場合、これにより UI フレームワークを移行せずに、UWP アプリで最新の .NET ランタイム機能を利用できます。
WinUI 3 の開発パターンについては、[skill:dotnet-winui] を参照してください。
UWP から Uno Platform への移行
UWP のコードベースを活用してクロスプラットフォームに対応する必要がある場合に適しています。Uno Platform は WinUI XAML API サーフェスを実装しているため、UWP からのクロスプラットフォーム移行先として最も自然な選択肢です。
Uno Platform は UWP XAML の基盤である WinUI XAML API サーフェスを使用するため、他のクロスプラットフォームフレームワークに移行する場合と比べて、多くの UWP コードを少ない変更で引き継げます。
- XAML ファイルは、最小限の変更で動作することがよくあります(Uno は
x:Bind、x:Loadなどをサポートしています) - ViewModel とサービスはそのまま引き継げます(プラットフォームに依存しないコード)
- Windows 固有 APIには、Windows 以外のターゲット向けのクロスプラットフォームな代替手段が必要です
主な検討事項
- プラットフォーム固有のコードで
Windows.*API を使用している場合、Windows 以外のターゲット向けに条件付きコンパイルまたは抽象化が必要です - WinRT API(センサー、地理位置情報、メディアキャプチャ)には、Uno の実装またはプラットフォーム固有の代替手段が必要です
- MSIX パッケージ化は Windows のみで利用できます。その他のプラットフォームでは、ネイティブの配布方法を使用します
Uno Platform の開発パターンについては、[skill:dotnet-uno-platform] を参照してください。ターゲットごとのデプロイについては、[skill:dotnet-uno-targets] を参照してください。
判断マトリックス
どの移行経路を選ぶかを決める際に、このマトリックスを使用してください。適切な選択肢は具体的な制約によって異なり、すべてに当てはまる「最善」の移行先はありません。
主な目標別
| 目標 | 推奨される移行経路 | 代替案 |
|---|---|---|
| リスクを最小限に抑え、迅速に移行する | WPF/WinForms から .NET 8+ へ | -- |
| モダンな Windows UI | WPF から WinUI 3 へ | Fluent テーマを使用した WPF .NET 9+ |
| Windows アプリからクロスプラットフォームへ | WPF から Uno Platform へ | 重要な部分を Blazor で書き換える |
| UWP からクロスプラットフォームへ | UWP から Uno Platform へ | UWP から WinUI 3 へ(Windows 専用のまま) |
| UWP のモダナイズ(Windows 専用) | UWP から WinUI 3 へ | .NET 9 プレビュー版で UWP を使用 |
| レガシー WinForms のモダナイズ | WinForms から .NET 8+ へ | Blazor または WPF で段階的に書き換える |
制約別
| 制約 | 最適な移行経路 | 理由 |
|---|---|---|
| 予算/時間が限られている | .NET 8+ への移行(同じフレームワーク) | 労力が最小限で、同じコードベースを維持できます |
| Windows 専用である必要がある | WinUI 3 または WPF .NET 8+ | モダンな UI には WinUI、変更を最小限にするには WPF |
| クロスプラットフォームにする必要がある | Uno Platform | WinUI XAML サーフェスを活用して、最も広範なプラットフォームに対応できます |
| 既存の WPF コードベースが大規模 | まず WPF .NET 8+ へ移行し、その後に評価する | UI を書き換える前に、最新のランタイムで安定させます |
| 既存の UWP コードベースがある | WinUI 3(Windows)または Uno(クロスプラットフォーム) | 既存のコードに最も近い API サーフェスです |
| チームにウェブ開発のスキルがある | Blazor(書き換え) | ウェブ開発の専門知識をデスクトップ/モバイルで活用できます |
段階的な移行戦略
大規模なアプリケーションでは、段階的なアプローチによってリスクを軽減できます。
- ステージ 1:ランタイムの移行 -- .NET Framework から .NET 8+ へ移行します(UI フレームワークはそのまま)。互換性を検証し、パフォーマンスを向上させ、最新の NuGet パッケージを利用できるようにします。
- ステージ 2:パターンのモダナイズ -- Host ビルダー、DI、MVVM Toolkit、モダンな C# を採用します。[skill:dotnet-wpf-modern] または [skill:dotnet-winforms-basics] を参照してください。
- ステージ 3:UI の移行(必要な場合)-- 要件に応じて WinUI 3、Uno Platform、または Blazor に移行します。ステージ 1 と 2 が安定している場合にのみ進めてください。
このアプローチにより、「一度にすべてを書き換える」リスクを回避し、各段階で段階的な価値を提供できます。
エージェントが陥りやすい注意点
- 制約を理解せずに、単一の移行先を「正しい選択肢」として推奨しないでください。 常にトレードオフを示し、複数の選択肢を提示してください。予算、スケジュール、チームの専門知識、プラットフォーム要件はすべて、判断に影響します。
- UI フレームワークの変更を提案する前に、.NET 8+ ランタイムへの移行を省略しないでください。 .NET Framework から .NET 8+ への移行(UI フレームワークはそのまま)をステージ 1 としてください。.NET Framework から WPF を WinUI に移行するほうが、.NET 8+ から移行するよりも大幅に困難です。
- WPF が「レガシー」で、移行が必須だと決めつけないでください。 .NET 8+ 上の WPF は、新機能(.NET 9+ の Fluent テーマやパフォーマンスの向上など)を伴って積極的にメンテナンスされています。多くのアプリケーションは、WPF を使い続けることで十分に役立ちます。
dotnet-upgrade-assistantを使う前に、必ずanalyzeを実行してください。 アップグレードの前に必ず分析し、変更範囲と潜在的な問題を把握してください。- WPF の XAML と WinUI の XAML を混同しないでください。 概念は似ていますが、API の範囲は異なります(
Window、DataContextとx:Bind、NavigationViewのパターンなど)。移行には、名前空間の変更以上の作業が必要です。 - UWP から WinUI 3 への移行には、名前空間の更新だけでなく、アプリモデルの変更も伴うことを忘れないでください。
Window.Current、CoreDispatcher、CoreApplicationの API はすべて、異なるパターンに置き換えられます。 - Windows 専用のシンプルなアプリに Uno Platform を推奨しないでください。 アプリケーションにクロスプラットフォーム対応が不要なら、WinUI 3 または WPF .NET 8+ のほうがシンプルで、メンテナンスの負担も少なくなります。