0
1

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 コードサンプル学習:17-BasicRegionNavigation

Posted at

Prism コードサンプル学習:17-BasicRegionNavigation

はじめに

以下の記事の続きです。
https://qiita.com/mngreen/items/c5ea46557522c8128593

17-BasicRegionNavigation

本サンプルは、RegionManager.RequestNavigateメソッドを用いてコントロールを切り替える例です。
実際にRegionManager.RegionNavigateを利用している箇所は以下です。
Navigateメソッドで受け取った引数の文字列にしたがい、ContentRegionの持つコントロールを切り替えています。

using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
namespace BasicRegionNavigation.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private readonly IRegionManager _regionManager;
        private string _title = "Prism Unity Application";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }
        public DelegateCommand<string> NavigateCommand { get; private set; }
        public MainWindowViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;
            NavigateCommand = new DelegateCommand<string>(Navigate);
        }
        private void Navigate(string navigatePath)
        {
            if (navigatePath != null)
                _regionManager.RequestNavigate("ContentRegion", navigatePath);
        }
    }
}

上記でコントロールを切り替えるためには、モジュール側で以下の通り事前に登録する必要があります。
登録時には名前を指定することもできますが、指定しない場合はその型通りの名前となる仕様のようです。

using ModuleA.Views;
using Prism.Ioc;
using Prism.Modularity;
namespace ModuleA
{
    public class ModuleAModule : IModule
    {
        public void OnInitialized(IContainerProvider containerProvider)
        {
        }
        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<ViewA>();
            containerRegistry.RegisterForNavigation<ViewB>();
        }
    }
}

コードを見る限り、RegionManagerとIContainerRegistryがお互いに参照関係を持たないとビューを切り替えられないように見えますがどのようにして連携しているのでしょうか?
RequestNavigateメソッドが呼び出されると、巡り巡ってRegionクラスのRequestNavigateメソッドが呼び出され、さらにRegionNavigationServiceクラスに委譲します。
NavigationServiceクラスを読み出し元を順に辿っていくと、RequestCanNavigateFromOnCurrentlyActiveViewメソッドにたどり着き、140行目を満たさない場合のみ(つまり、currentViewIndex >= activeViews.Length。ただ、あまり意図がわかっていない。遷移させたいビューがアクティブでないときに限って遷移させるということ?)、ExecuteNavigationメソッドを実行します。 この中でCreateNewRegionItemメソッドが呼び出されることでコンテナーからViewインスタンスを生成し、ようやくRegionに対してViewが追加されます(https://github.com/PrismLibrary/Prism/blob/7f0b1680bbe754da790274f80851265f808d9bbf/src/Wpf/Prism.Wpf/Regions/RegionNavigationContentLoader.cs#L51)。

つまり、RegionManager-Region-RegionNavigationService-IContainerExtension(IContainerRegistry)という関連を持つことで、上記の振る舞いが実現できているようでした。

おわりに

今回は、RegionManager.RequestNavigateメソッドを用いてコントロールを切り替える例についてコードを読みました。
ユーザーから見ると型の文字列を入力にわたすだけで簡単にコントロールが切り替えられているようにみるのですが、その裏には責務ごとに切り分けられたI/Fとクラスが存在しており、緻密に連携して見えました。
次回、18-NavigationCallbackについて見ていこうと思います。

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?