VB のたまご

作成日: 2017/05/14, 更新日: 2017/05/14



Region1

  •  ここでは、Region(リージョン、区画)について学習します。

  • イメージ
    スポンサーリンク


  •  Region の立ち位置的には、 WinForms で言うと Panel を下地に敷いておいて、プログラム上で、Panel に UserControl を埋め込んで動的に表示したり、 別の UserControl をセットして切り替え表示するような、そういうイメージに近いです。

  •  つまり、画面内に部分的な目印、マーキングだけしておき、後から(プログラム実行時に) UserControl をインジェクションして表示する機能です。 この考え方は、機能分割と作業分担から来ています。 1つのアプリケーションは、1つのまとまりとして扱うよりも、より細分化して機能を小さくした方が、各チームでやりやすいですよね。

  •  最終的に1つの画面に、いろいろな機能を持たせるけど、各機能は追加したり削除したりしやすい(区画名を書くだけだから)、 また、修正もしやすいし、メイン画面に影響が無い(区画名しか書いていないから)、というメリットがあります。 特にプロジェクト分割しているときに効力を発揮します。 ただし、実行するまで画面全体を見られないことがデメリットです。

  •  それでは、区画名を割り当ててみましょう。

  • <Window x:Class="Views.Window1"xmlns:prism="http://prismlibrary.com/"
            ~>
            
        <Grid>
    
            <ContentControl prism:RegionManager.RegionName="ContentRegion" />
    
        </Grid>
        
    </Window>
    

  •  区画を割り当てるのは簡単です。ContentControl コントロールに区画名を書くだけです。 RegionManager クラスの RegionName プロパティに、一意を識別できる任意の区画名をセットします。 区画のサイズや表示位置は、コントロールのサイズや表示位置とイコールになります。

  •  それでは、指定した区画に、画面をインジェクションしてみましょう。 以下は同じプロジェクト内に作成した UserControl で、文字列を表示するだけのコントロールです。

  • <UserControl x:Class="Views.SubView"
                 ~>
        
        <Grid>
    
            <TextBox Text="Hello, Prism! from UserControl" />
    
        </Grid>
        
    </UserControl>
    

  •  作成した UserControl は、後で ViewModel にインジェクションする処理を書きたいので、 ViewModel からでも呼び出せるように、Unity コンテナに登録しておきます。

  •  ブートストラッパーに以下のメソッドを追加します。 ViewModel では、View の画面クラスを知らないので(型を指定できないので)、Object 型かつ画面名と名付けて、名前で判断できるようにしておきます。

  • Protected Overrides Sub ConfigureContainer()
        MyBase.ConfigureContainer()
    
        ' ViewModel から指定できるように、Object 型の SubView 名で登録しておく
        Me.Container.RegisterType(Of Object, SubView)("SubView")
    
    End Sub
    

  •  続いて、ViewModel に画面をインジェクションする処理を書いていきます。 ※ View に【prism:ViewModelLocator.AutoWireViewModel="True"】を書いておくのを忘れないでくださいね。

  • Imports Prism.Regions
    Imports Microsoft.Practices.Unity
    
    Namespace ViewModels
    
        Public Class Window1ViewModel
    
            Public Property Title As String = "Prism Unity Application"
    
            ' Unity コンテナ経由でインスタンス生成されてくるため、コンストラクタの引数にしている、
            ' IRegionManager と IUnityContainer インターフェースには、RegionManager と UnityContainer クラスのインスタンスが渡ってくる
            Public Sub New(manager As IRegionManager, container As IUnityContainer)
    
                ' ContentRegion 区画に、SubView ユーザーコントロールを登録(インジェクション)する
                manager.RegisterViewWithRegion("ContentRegion", Function() container.Resolve(Of Object)("SubView"))
    
            End Sub
    
        End Class
    
    End Namespace
    

  •  Prism.Regions.IRegionManager マネージャーが、区画処理を担当します。 Microsoft.Practices.Unity.IUnityContainer コンテナは、以前勉強した Unity コンテナです。 シングルトン形式ではないですが、どこからでも呼び出して、任意のインスタンスを取得することができます。 ここでは、View にある画面のインスタンスを取得したいため使っています。

  •  ViewModel のコンストラクタ・インジェクションで渡ってきた2つのクラスを使って、画面をインジェクションします。 区画へのインジェクションは、IRegionManager インターフェースの RegisterViewWithRegion メソッドを使って、 区画名とインジェクションしたい画面のインスタンスを渡します。

  •  実行すると、Window1 画面に UserControl コントロールが埋め込まれていることが分かると思います。

  • スポンサーリンク


  •  以下、ソース全体です。 画面クラスのコードビハインドには、名前空間の追加以外、処理はありません。

  •  Window1ViewModel.vb

  • Imports Prism.Regions
    Imports Microsoft.Practices.Unity
    
    Namespace ViewModels ' ←名前空間を追加する
    
        Public Class Window1ViewModel
    
            Public Property Title As String = "Prism Unity Application"
    
            ' Unity コンテナ経由でインスタンス生成されてくるため、コンストラクタの引数にしている、
            ' IRegionManager と IUnityContainer インターフェースには、RegionManager と UnityContainer クラスのインスタンスが渡ってくる
            Public Sub New(manager As IRegionManager, container As IUnityContainer)
    
                ' ContentRegion 区画に、SubView ユーザーコントロールを登録(インジェクション)する
                manager.RegisterViewWithRegion("ContentRegion", Function() container.Resolve(Of Object)("SubView"))
    
            End Sub
    
        End Class
    
    End Namespace
    

  •  Window1.xaml

  • <Window x:Class="Views.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication1.Views"
            xmlns:prism="http://prismlibrary.com/"
            prism:ViewModelLocator.AutoWireViewModel="True"
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            mc:Ignorable="d"
            Title="{Binding Title}" Height="350" Width="525">
    
        <Grid>
    
            <!--
            RegionManager クラスを使って、任意の区画を作ります
            ここに、UserControl をインジェクションして表示させます
            
            -->
            <ContentControl prism:RegionManager.RegionName="ContentRegion" />
    
        </Grid>
        
    </Window>
    

  •  SubView.xaml

  • <UserControl x:Class="Views.SubView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:WpfApplication1.Views"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        
        <Grid>
    
            <TextBox Text="Hello, Prism! from UserControl" />
    
        </Grid>
        
    </UserControl>
    

  •  Bootstrapper.vb

  • Imports Microsoft.Practices.Unity
    Imports Prism.Unity
    Imports WpfApplication1.Views
    
    Public Class Bootstrapper
        Inherits UnityBootstrapper
    
        ' Shell 担当になる View のインスタンスを返却
        Protected Overrides Function CreateShell() As DependencyObject
            Return Me.Container.Resolve(Of Window1)
        End Function
    
        ' Shell 担当になる View を表示
        Protected Overrides Sub InitializeShell()
            Application.Current.MainWindow.Show()
        End Sub
    
        ' Unity コンテナの設定
        Protected Overrides Sub ConfigureContainer()
            MyBase.ConfigureContainer()
    
            ' ViewModel から指定できるように、Object 型の SubView 名で登録しておく
            Me.Container.RegisterType(Of Object, SubView)("SubView")
    
        End Sub
    
    End Class
    

  •  Application.xaml.vb 
  •  ※Application.xaml では、【StartupUri="MainWindow.xaml"】を削除しています。

  • Class Application
    
        ' Startup、Exit、DispatcherUnhandledException などのアプリケーション レベルのイベントは、
        ' このファイルで処理できます。
    
        Protected Overrides Sub OnStartup(e As StartupEventArgs)
            MyBase.OnStartup(e)
    
            ' Unity 管理による Prism アプリケーションの起動制御処理を実行
            Dim boot = New Bootstrapper
            boot.Run()
    
        End Sub
    
    End Class