24.5K Views
April 28, 22
スライド概要
こちらのイベントで発表した資料です。
https://csharp-tokyo.connpass.com/event/243622/
Windows Template Studioで GenericHost+MVVMなWPFアプリを手軽に 書いてみる
自己紹介 ID:suusanex( connpass・Twitter・GitHub共通) 名前:須藤圭太 サイエンスパーク株式会社という独立系ソフトウェアベンダーに所属 4年ほど受託開発で、上流から下流まで全部を回す ここ6年ほどは、自社製品開発を担当 Windowsアプリ開発のネタが多い 勉強会もやってます。 https://sciencepark.connpass.com
概要 WPFといえばMVVM その割に、普通にWPFアプリを作るとMVVMにならないので、フレームワーク が色々ある とはいえ、MVVMフレームワークを使いこなしてコードを書ける人はなかなか いないし、一からの学習は大変 MSが出してるテンプレートのコードを使ってみた(Windows Template Studio) 楽に書けたので、同レベルのにわかWPF使いにはお勧め 使い方を簡単に紹介してみます(知ってる人は退屈かも)
使い方:コードの生成方法1 Visual Studio 2019に拡張「WindowsTemplateStudio」をインストール https://marketplace.visualstudio.com/items?itemName=WASTeamAccount.Window sTemplateStudio 注意:.NET Core 3.1 + VS2019のまま更新が止まっているので、最新情報ではない 最新ではないが、生成されたコードを.NET 6 + VS2022用に少し書き換えれば、この 目的なら十分に使える 有志がVisual Studio 2022用にフォークして別プロジェクトを作っているようなので、 そちらを使うのもあり https://marketplace.visualstudio.com/items?itemName=MattLaceyLtd.TemplateSt udioForWPF 2022/4/23現在、生成されるコードはどちらも同じ
使い方:コード の生成方法2 プロジェクト追加で、 「Template」を検索 WPF .NET Coreを選択
設定画面のポイント Prismが定番と聞くが、.NET標準となりそうなGenericHostを使っていきたい なので、MVVMToolKit
生成されたプロジェクト こんな感じのコードが出来上がる MVVMが分かれているのはもちろん 基本的な仕組みのコードが色々生成 される
.NET 6用に変更 プロジェクトのターゲットを.NET 6に プロジェクトファイルのSDK部分を 「Microsoft.NET.Sdk」に変更 これだけで、特に問題なく .NET 6で動作する
生成されたコードのポイント あとはビルドすれば動きます。 それではさすがに短すぎるので、生成されたコードを書き換えるうえでポイン トになる部分をいくつか紹介します。 GenericHostの部分 DIの使い方 ページの追加の仕方(Blank設定で生成されたコードは、ウインドウ1つにフ レームがあってページを増やす形) Microsoft.Toolkit.Mvvm MahApps.Metro
生成コード:GenericHost部分
GenericHostは、ロガーやサービス登録やDIなどの仕組みをまとめて管理して
ロジックから切り離せる、.NETの仕組み(詳しくはここでは触れません)
https://docs.microsoft.com/ja-jp/dotnet/core/extensions/generic-host
GenericHostはすでにApp.xaml.csへ組み込まれている
ConfigureServiceを通してWPFの最初のウインドウを開くところまでコード作
成済み
すぐ使えるし、必要なExtentionがあれば足せば良い
ログなどの必要な
Extentionを足せる
private async void OnStartup(object sender, StartupEventArgs e)
{
var appLocation = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
_host = Host.CreateDefaultBuilder(e.Args)
.ConfigureAppConfiguration(c =>
{
c.SetBasePath(appLocation);
})
.ConfigureServices(ConfigureServices)
.Build();
await _host.StartAsync();
}
生成コード:DI Microsoft.Extensions.DependencyInjectionを組み込み済み コンテナ登録したものを各ViewModel等のコンストラクタで受け取れる コンテナ登録はApp.xaml.csのConfigureServicesメソッドにあるので、そこに 足せば良い private void ConfigureServices(HostBuilderContext context, IServiceCollection services) { ~略~ // Services services.AddSingleton<IPageService, PageService>(); services.AddSingleton<INavigationService, NavigationService>(); // Views and ViewModels services.AddTransient<IShellWindow, ShellWindow>(); 自作クラスのコンテナ 登録をここに足す
生成コード:ページ追加
生成コードは、WindowとFrameが1つあって、その中でPageを遷移するもの
ページをDictionaryに登録しておくと、NavigationServiceで生成と遷移をまと
めてやってくれる(そういうコードを生成済み)
public class PageService : IPageService
{
public PageService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
自作Page(View)とViewModel
Configure<MainViewModel, MainPage>();
のペアをここに追加
}
登録したページへは、NavigationService.NavigateToで、ViewModelの名前指定
で生成・遷移できる
_navigationService.NavigateTo(typeof(MainViewModel).FullName);
Microsoft.Toolkit.Mvvm WPFをMVVMで書くためのMS標準フレームワークの一つ https://docs.microsoft.com/en-us/windows/communitytoolkit/mvvm/introduction 今回生成したコードは、これを理解して使う前提になっている シンプルな最低限の作りなので、検索すればだいたい情報は出てくる 名前が変わったり統合されたりしているので、検索で次の名前が出てきたら全 部同じものと思って良い Microsoft.Toolkit.Mvvm MVVM Toolkit MVVM Light Toolkit
MahApps.Metro 生成コードに組み込まれているが、独立したライブラリ だいぶ古いまま取り残されたWPFのUIを、ちょっと最近のWindowsっぽくする https://mahapps.com スタイルとカスタムコントロールで構成されている 標準のWPFの画面が良ければ、App.xamlからスタイルを外して、MetroWindow クラスをWindowクラスに置き換えればOK
まとめ Windows Template Studioでテンプレートコード生成という選択肢を紹介した GenericHostベースのMVVMのコードをすぐに書ける コード例を読みながら理解できる WPFで書いてるけどMVVMよく分かってないとか、GenericHostが気になってる 人は、使ってみよう