今まで何となくで触っていたPrismでしたが、一度しっかりソースコードを読み込んで見ようと思ったので記録として残します。
読み返した時にチートシート的な使い方ができるよう、ソースにコメントを入れていくスタイルでいきます。
02-Region
今回はサンプル02-Regionを読みます。
Prismの用語✨🌈
Region📟
画面領域の単位。一つのShell(=Window)に一つもしくは複数のRegionを配置できる。
https://elf-mission.net/programming/wpf/getting-started-2020/step05/#Module_View
ソースコードを読む📑
今回はManiWindowに挿入されたRegionとRegionにViewを登録する方法まで見る
まずはサンプルのMainWindow.xaml
と MainWindowViewModel.cs
<!--MainWindow.xmal-->
<Window x:Class="Regions.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
Title="Shell" Height="350" Width="525">
<Grid>
<!--「ContentRegion」という名前の領域ここに他のViewを入れられる。-->
<ContentControl prism:RegionManager.RegionName="ContentRegion" />
</Grid>
</Window>
// MainWindowViewModel.cs
public class MainWindowViewModel
{
private readonly IRegionManager _regionManager;
public MainWindowViewModel(IRegionManager regionManager)
{
_regionManager = regionManager; // Boostrapper内でIRegionManagerはRegionManagerにDIされているので引数に入れるだけで実態を取得できる
_regionManager.RegisterViewWithRegion("ContentRegion", typeof(Views.SubView1)); // "ContentRegion"というRegionに"SubView1"というViewを入れている。
}
}
IRegionManagerの実態RegionManagerクラス で今回関係ありそな箇所を読む。
RegionManagerにできること📟
// やってることは
public interface IRegionManager
{
IRegionCollection Regions { get; } // 一つのRegionManagerView(IRegion)のコレクションを持つprivateクラス。
IRegionManager CreateRegionManager(); // 新しいRegionManagerをreturn。
// AddToRegion()とRegisterViewWithRegion()はどちらもViewを登録するメソッドだが
IRegionManager AddToRegion(string regionName, object view); // 既存のRegionにViewを加える。
IRegionManager RegisterViewWithRegion(string regionName, Type viewType); // RegionをDIで明示的にDIしていなくても、RegionをDIしViewをそのRegionに加える
var regionViewRegistry = ContainerLocator.Container.Resolve<IRegionViewRegistry>(); // RegionViewRegistoryクラス(RegionとList<View>の組み合わせを持つクラス)
regionViewRegistry.RegisterViewWithRegion(regionName, viewType); // regionNameのRegionにviewType(DIコンテナに登録してある)を登録
return this;
IRegionManager RegisterViewWithRegion(string regionName, Func<object> getContentDelegate); //Viewクラスを返すFunc<object>を入れる
// 以下は画面へ遷移用メソッドRequestNavigate()のオーバーロード
}
まとめ
AddToRegion()
と RegisterViewWithRegion
の使い分けがややこしく、AddToRegion
の場合はRegion
を事前に実体化させたものを使うかDIさせて置く必要があるようなのですが、 手元の環境で動かすとどうもRegion
の登録がうまく行かないようで例外がスローされてしまいました。
RegisterViewWithRegion
でRegion
を登録し、同一のRegion
を使えばViewを登録できるのかと思えばこれもエラー。
Region
を使いまわしたい時などに使うのかと思ったのですが、いまいち使い道がよくわかりませんでした。
今後ソースを読む中で理解が深まれば追記したいと思います。