Prism コードサンプル学習：06-ViewActivationDeactivation

# Prism コードサンプル学習：06-ViewActivationDeactivation

## はじめに

以下の記事の続きです。
<https://qiita.com/mngreen/items/2d1d3243f1514eccebcf>

## 06-ViewActivationDeactivation

本サンプルではRegionクラスを用いて、対象regionのViewをActivate、またはDeactivateすることで表示・非表示が切り替えています。

```xml
<Window x:Class="ActivationDeactivation.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">
    <DockPanel LastChildFill="True">
        <StackPanel>
            <Button Content="Activate ViewA" Click="Button_Click"/>
            <Button Content="Deactivate ViewA" Click="Button_Click_1"/>
            <Button Content="Activate ViewB" Click="Button_Click_2"/>
            <Button Content="Deactivate ViewB" Click="Button_Click_3"/>
        </StackPanel>
        <ContentControl prism:RegionManager.RegionName="ContentRegion" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </DockPanel>
</Window>
```

```csharp
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        IContainerExtension _container;
        IRegionManager _regionManager;
        IRegion _region;

        ViewA _viewA;
        ViewB _viewB;

        public MainWindow(IContainerExtension container, IRegionManager regionManager)
        {
            InitializeComponent();
            _container = container;
            _regionManager = regionManager;

            this.Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            _viewA = _container.Resolve<ViewA>();
            _viewB = _container.Resolve<ViewB>();

            _region = _regionManager.Regions["ContentRegion"];

            _region.Add(_viewA);
            _region.Add(_viewB);
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //activate view a
            _region.Activate(_viewA);
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            //deactivate view a
            _region.Deactivate(_viewA);
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            //activate view b
            _region.Activate(_viewB);
        }

        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            //deactivate view b
            _region.Deactivate(_viewB);
        }
    }
```

- [Activate ViewA], [Activate ViewB]ボタンを押下することで、ContentRegionにViewが表示されます。
- [Deactivate ViewA], [Deactivate ViewB]ボタンを押下することで、ContentRegionのViewが非表示になります。
- ただし、複数がアクティブになることはありません。
  - ViewAをアクティブ→ViewBをアクティブ→ViewBを非アクティブにしても、ViewAはアクティブとはならない。
- [Activate](https://github.com/PrismLibrary/Prism/blob/master/src/Wpf/Prism.Wpf/Regions/Region.cs#L300)メソッドが呼び出されると引数に渡されたビューのItemMetadataを取得し、そのIsActiveプロパティをtrueにする。
- [Deactivate](https://github.com/PrismLibrary/Prism/blob/master/src/Wpf/Prism.Wpf/Regions/Region.cs#L314)メソッドが呼び出されると引数に渡されたビューのItemMetadataを取得し、そのIsActiveプロパティをfalseにする。
- ContentControlRegionAdapterクラスに着目。
  - ContentControlRegionではRegionを生成する際に、Activeとなるビューが一つとなるSingleActiveRegionを生成する。このクラスでは他のクラスがアクティブになると、現在アクティブなビューは非アクティブになってしまう。そのため複数のViewがアクティブにならない。

<!-- Activateメソッドが呼び出されるとビューが切り替わる理由は、ItemMetadataのプロパティが変わったときのMetaDataChangedイベントのイベントハンドラである[OnItemMetadataChanged](https://github.com/PrismLibrary/Prism/blob/master/src/Wpf/Prism.Wpf/Regions/ViewsCollection.cs#L176)による結果。IsInListプロパティは初期値ではfalse（IsInListのセットされるタイミングは[AddMetadataMonitor](https://github.com/PrismLibrary/Prism/blob/master/src/Wpf/Prism.Wpf/Regions/ViewsCollection.cs#L150)メソッドのみであるが、その利用箇所を更にたどるとMonitorAllMetadataItemsメソッドのみで、そのfilterの結果が[_activeViews](https://github.com/PrismLibrary/Prism/blob/master/src/Wpf/Prism.Wpf/Regions/Region.cs#L138)の場合は、IsActiveの値に依存しており、IsActiveプロパティの初期値がfalseであるため）なので、NotifyAddが実行されて巡り巡ってCollectionChangedイベントが通知されるため。-->

## おわりに

今回はRegionクラス, ContentControlRegionAdapterクラス, SingleActiveRegionクラスのソースコードを中心に読みました。
以前の章で紹介されたように、XXXRegionAdapterクラスを利用することで、Active時のUIをコントロールすることができるといった事例として学ぶことができました。
次回、07-Modulesについて見ていこうと思います。