2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Prism.WpfのDialogServiceからのDialogでRegionを使いたい

2
Posted at

内容

Prism.WpfDialogServiceから呼び出したDialogの中にRegionを加えてRequestNavigateしたけれども、
ちょっと手を加えないと遷移しなかったため、その方法について記載します。

環境

結論

DialogServiceを継承したクラスを用意して(ソース)

protected virtual void ConfigureDialogWindowContent(string dialogName, IDialogWindow window, IDialogParameters parameters)

をオーバーライドして

dialogservice
        protected override void ConfigureDialogWindowContent(string dialogName, IDialogWindow window, IDialogParameters parameters)
        {
            var rm = _regionManager.CreateRegionManager();
            RegionManager.SetRegionManager(window as Window, rm);
            RegionManager.UpdateRegions();

            parameters.Add("rm", rm);

            base.ConfigureDialogWindowContent(dialogName, window, parameters);
        }

こんな感じでRegionManagerを新規に作成し、Dialogとして表示されるWindowに割り当てます。
ViewModelにRegionManagerを伝えるためにIDialogParametersにインスタンスを追加します。

ViewModel側でRegionManagerを受け取ってRequestNavigateします。(ソース)

viewmodel
        public void OnDialogOpened(IDialogParameters parameters)
        {
            if (parameters.TryGetValue<IRegionManager>("rm", out IRegionManager rm))
                CustomDialogARegionManager = rm;

            if (parameters.TryGetValue<string>("ViewName", out string v))
                CustomDialogARegionManager.RequestNavigate("CustomDialogARegion", v);
            else
                CustomDialogARegionManager.RequestNavigate("CustomDialogARegion", "CustomDialogAAView");
        }

Region間でのRequestNavigateはIRegionNavigationServiceを使用すれば意識する必要がなくなります。(参考)

発端

<ContentControl prism:RegionManager.RegionName="MyRegion" prism:RegionManager.RegionManager="{Binding MyRegionManager}" />

こんな感じでRegionManager添付プロパティを指定すれば出来ると思って実装したのですが出来ませんでした。

調べてみるといくつか言及している質問がありました。

いくつか抜粋してグーグル翻訳してみると

  • 問題は、リージョンがビジュアルツリーでRegionManagerのアタッチされたプロパティを検索し、そのマネージャーに登録することです。メインウィンドウでは問題ありませんが、子ウィンドウではこれは発生しません。
  • プレゼンタークラスのコンストラクターにリージョンマネージャーを登録する必要がありました。 そうすれば、新しいウィンドウのリージョンでグローバルリージョンマネージャーを見つけることができます。
  • DialogServiceによって作成されたダイアログを含むサブウィンドウに自動的に継承されることはありません。したがって、ダイアログでリージョンを使用する場合は、リージョンマネージャーを手動でアタッチする必要があります。

等々。
メイン画面ではPrismさんが良い感じにアタッチしてくれてるみたいなのですが、新規に作成したWindowに関しては自分でアタッチしないといけないみたいです。

修正案

  1. Dialogで表示させるViewで個々にアタッチする実装を行う
  2. 一律Dialogに新規のRegionManagerをアタッチする実装を行う
  3. DialogではRegionを使用しない
  4. etc

とりあえず2.の方向で検討し、上記のような実装になりました。
デメリットですが、IDialogParametersを経由してRegionManagerの受け渡しを行うため、
それのキー(今回だと"rm")が予約語的になってしまうところです。
開発者間でわかっていれば問題ないことですが暗黙知になりそうです。

最後に

Prism.Wpfの7から8の変化として

等がありました。他にもあると思います。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?