51.7K Views
June 19, 22
スライド概要
次のイベントでの発表資料です。
https://csharp-tokyo.connpass.com/event/247353/
Template Studioのコー ドを見て、WPFから MAUI(WinUI3)への移 行を考える 2022/6/19 須藤(suusanex)
自己紹介 ID:suusanex( connpass・Twitter・GitHub共通) 名前:須藤圭太 サイエンスパーク株式会社という独立系ソフトウェアベンダーに所属 4年ほど受託開発で、上流から下流まで全部を回す ここ8年ほどは、自社製品開発も担当 Windowsアプリ開発のネタが多い 勉強会もやってます。 https://sciencepark.connpass.com
Buildでの注目ポイント MAUIがついに!クロスプラットフォームは重要なのは確か 一方、Windowsアプリだけの開発の視点だと・・・ 重要なのは、それと合わせて登場したWindows App SDK 1.1 WinUI 3が色々アップデート https://blogs.windows.com/windowsdeveloper/2022/06/03/whats-new-inwindows-app-sdk-1-1/ WinUI 3のTemplate Studioが登場! Template Studio for WinUI (C#) - Visual Studio Marketplace
WPFからWinUI 3への移行可能性を考える MVVM Toolkitを使ったテンプレートを生成してくれるWPF・UWPの同名機能は すでにあった 参考: Windows Template StudioでGenericHost+MVVMなWPFアプリを手軽に 書いてみる | ドクセル (docswell.com) それのWinUI 3版が出たことで、それを使っていたコードは移行しやすくなる はず 比較して移行可能性を考えてみる
テンプレートの選択肢 WPFの時と基本的に同じ Prismが消えてMVVMToolkitだけに(当たり前か)
テンプレートの注意点 デフォルトだとMSIX Packagingが入っている ストア経由での配信前提で、デバッグにも開発者モード設定など一手間必要 WPFと同じ感覚でexeそのまま配布・デバッグ実行をしたい場合は、 MSIX Packagingを消してSelf-Containedを追加 追加 消す
App.xaml.cs
GenericHostを使っていて、基本はWPFと同じっぽい
private static readonly IHost _host = Host
.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{・・・
ごく普通のGenericHost
WPFではShellWindowというWindowにFrameを置いていたが、標準のWindow
へShellPageを入れる形になった
流れは変わったが、
やってることは同じ
public static Window MainWindow { get; set; } = new Window() { Title =
"AppDisplayName".GetLocalized() };
_shell = App.GetService<ShellPage>();
App.MainWindow.Content = _shell ?? new Frame();
起動~ウインドウ表示までの処理 ApplicationServiceがActivationServiceになった protected async override void OnLaunched(LaunchActivatedEventArgs args) { base.OnLaunched(args); var activationService = App.GetService<IActivationService>(); await activationService.ActivateAsync(args); } InitializeAsync・StartupAsyncなど、メソッド命名は同じ感じ 流れは変わったが、 やってることは同じ public async Task ActivateAsync(object activationArgs) { // Execute tasks before activation. await InitializeAsync(); ・・・ これらメソッドを実装していた // Activate the MainWindow. なら、そのまま移行できそう App.MainWindow.Activate(); // Execute tasks after activation. await StartupAsync();
PageのNavigation(DI付き)
テンプレートで生成されるコードに入っている仕組み
NavigateToメソッドを呼び出すだけで、ViewModel&ViewをDIで生成して
Navigateしてくれる
NavigationService,PageServiceなど、WPFの時と同じ内容だった
public class PageService : IPageService
{
private readonly Dictionary<string, Type>
_pages = new();
そのまま移行できそう
public PageService()
{
Configure<MainViewModel, MainPage>();
}
_navigationService.NavigateTo(typeof(MainViewModel).FullName, args.Arguments);
ViewModel Microsoft.Toolkit.Mvvm v7がCommunityToolKit.Mvvm v8(preview)に(おそらく後継) ObservableRecipientというクラスの継承に変わった public class ShellViewModel : ObservableRecipient これはWPFで使われていたObservableObjectの継承クラス namespace CommunityToolkit.Mvvm.ComponentModel { public abstract class ObservableRecipient : ObservableObject つまり、引き続きMicrosoft MVVM Toolkitの実装をそのまま使える 適当なPageを移行してみたところ、名前空間の変更だけで問題なく行けた そのまま移行できそう
プロジェクト WPFとそう変わらない UseWPFの代わりに<UseWinUI>true</UseWinUI> UseWPFも定義できる→ただし現バージョンではコンパイルエラー 移行は簡単そうだが、 WPFとWinUIの共存はダメっぽい (今後のバージョンでできるかも?) <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework> <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion> ・・・ <UseWinUI>true</UseWinUI>
まとめ MVVMの作りは同じで、MVVM Toolkit部分もそのまま使えるようだ つまり既存WPFプロジェクトのViewだけを差し替えてWinUI3へ移行することは、 難しくなさそう Template Studio(WPF)で作っておけば、Template Studio(WinUI)とコード上の 対応が取れていてさらにやりやすそう Win UI3の移行を検討しつつ、とりあえずは確実なWPFで作成する、というア プローチが問題なく出来そう