VB のたまご

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



Region5

  •  引き続き、Region です。 任意に割り当てた区画に対して遷移する時に、一緒にデータを渡すことができます。 今回はこの方法を学習します。

  • スポンサーリンク


  •  まず、View 側では、データを渡すコードを書きます。 今回のサンプルでは、リストボックス内にある複数の項目のうち、選択中の項目を渡すデータとして指定しています。

  • <ListBox 
        DockPanel.Dock="Top"
        Name="listbox1" 
        ItemsSource="{Binding People}" />
    
    <!-- ListBox.SelectedItem 1つ分のバインドデータは、PersonModel 型になります -->
    <ContentControl
        prism:RegionManager.RegionName="DetailRegion"
        prism:RegionManager.RegionContext="{Binding ElementName=listbox1, Path=SelectedItem}" />
    

  •  続いて、DetailRegion 区画にインジェクションする処理を記載します。 ここでは、別プロジェクト内の画面をインジェクションするため、その別プロジェクト内にあるモジュール内に記載しています。

  • Public Sub Initialize() Implements IModule.Initialize
    
        Me.Manager.RegisterViewWithRegion("DetailRegion", GetType(DetailView))
    
    End Sub
    

  •  RegionContext プロパティ経由で渡したデータは、画面クラスのコードビハインドで受け取ります。 ここでは、DetailView ユーザーコントロールですね。

  • Public Class DetailView
    
        Public Sub New()
    
            ' この呼び出しはデザイナーで必要です。
            InitializeComponent()
    
            ' InitializeComponent() 呼び出しの後で初期化を追加します。
            AddHandler RegionContext.GetObservableContext(Me).PropertyChanged, AddressOf Me.DetailView_PropertyChanged
    
        End Sub
    
        Private Sub DetailView_PropertyChanged(sender As Object, e As PropertyChangedEventArgs)
    
            Dim context = CType(sender, ObservableObject(Of Object))
            Dim selectedPerson = CType(context.Value, PersonModel)
            CType(Me.DataContext, DetailViewModel).SelectedPerson = selectedPerson
    
        End Sub
    
    End Class
    

  •  DetailView のコンストラクタ内で、RegionContext クラスの GetObservableContext メソッドを呼び出して、 自分宛てのデータがあったら、データを受け取るようにイベントを購読します。

  •  イベントハンドラでは、送られてきたデータをキャストして任意の型に戻して、つまり選択中の項目の型に戻して、 バインド中の ViewModel のメンバーを上書き更新しています。

  •  このサンプルを実行すると、リストが表示されますので任意の項目を選択することで、詳細情報が表示更新されます。

  • スポンサーリンク


  •  それでは、以下ソース全体です。

  •  モジュールのプロジェクト

  •  PersonModel.vb

  • Imports Prism.Mvvm
    
    Namespace Models
    
        Public Class PersonModel
            Inherits BindableBase
    
            Private _FirstName As String
            Public Property FirstName() As String
                Get
                    Return _FirstName
                End Get
                Set(ByVal value As String)
                    Me.SetProperty(_FirstName, value)
                End Set
            End Property
    
            Private _LastName As String
            Public Property LastName() As String
                Get
                    Return _LastName
                End Get
                Set(ByVal value As String)
                    Me.SetProperty(_LastName, value)
                End Set
            End Property
    
            Private _Age As Integer
            Public Property Age() As Integer
                Get
                    Return _Age
                End Get
                Set(ByVal value As Integer)
                    Me.SetProperty(_Age, value)
                End Set
            End Property
    
            ' ListBox に名前空間が表示されてしまうため表示データを加工
            Public Overrides Function ToString() As String
                Return $"{Me.LastName}, {Me.FirstName}"
            End Function
    
        End Class
    
    End Namespace
    

  •  DetailViewModel.vb

  • Imports Prism.Mvvm
    Imports ClassLibrary1.Models
    
    Namespace ViewModels
    
        Public Class DetailViewModel
            Inherits BindableBase
    
            Private _SelectedPerson As PersonModel
            Public Property SelectedPerson() As PersonModel
                Get
                    Return _SelectedPerson
                End Get
                Set(ByVal value As PersonModel)
                    Me.SetProperty(_SelectedPerson, value)
                End Set
            End Property
    
        End Class
    
    End Namespace
    

  •  DetailView.xaml

  • <UserControl x:Class="Views.DetailView"
                 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:ClassLibrary1.Views"
                 xmlns:prism="http://prismlibrary.com/"
                 prism:ViewModelLocator.AutoWireViewModel="True">
        
        <!-- 以下に加えて、コードビハインドで RegionContext を受け取ります -->
        
        <Grid Background="White">
    
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
    
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
    
            <!-- First Name -->
            <TextBlock Text="First Name:" Margin="5" />
            <TextBlock Grid.Column="1" Margin="5" Text="{Binding SelectedPerson.FirstName}" />
    
            <!-- Last Name -->
            <TextBlock Grid.Row="1" Text="Last Name:" Margin="5" />
            <TextBlock Grid.Row="1" Grid.Column="1"  Margin="5" Text="{Binding SelectedPerson.LastName}" />
    
            <!-- Age -->
            <TextBlock Grid.Row="2" Text="Age:" Margin="5"/>
            <TextBlock Grid.Row="2" Grid.Column="1"  Margin="5" Text="{Binding SelectedPerson.Age}"/>
            
        </Grid>
        
    </UserControl>
    

  •  DetailView.xaml.vb

  • Imports Prism.Regions
    Imports Prism.Common
    Imports System.ComponentModel
    
    Imports ClassLibrary1.Models
    Imports ClassLibrary1.ViewModels
    
    Namespace Views
    
        Public Class DetailView
    
            Public Sub New()
    
                ' この呼び出しはデザイナーで必要です。
                InitializeComponent()
    
                ' InitializeComponent() 呼び出しの後で初期化を追加します。
                AddHandler RegionContext.GetObservableContext(Me).PropertyChanged, AddressOf Me.DetailView_PropertyChanged
    
            End Sub
    
            Private Sub DetailView_PropertyChanged(sender As Object, e As PropertyChangedEventArgs)
    
                Dim context = CType(sender, ObservableObject(Of Object))
                Dim selectedPerson = CType(context.Value, PersonModel)
                CType(Me.DataContext, DetailViewModel).SelectedPerson = selectedPerson
    
            End Sub
    
        End Class
    
    End Namespace
    

  •  ClassLibrary1Module.vb

  • Imports Microsoft.Practices.Unity
    Imports Prism.Regions
    Imports Prism.Modularity
    Imports ClassLibrary1.Views
    
    Public Class ClassLibrary1Module
        Implements IModule
    
        <Dependency>
        Public Property Manager As IRegionManager
    
        Public Sub Initialize() Implements IModule.Initialize
    
            Me.Manager.RegisterViewWithRegion("DetailRegion", GetType(DetailView))
    
        End Sub
    
    End Class
    

  •  続いて、WPF アプリケーションプロジェクト

  •  Window1ViewModel.vb

  • Imports System.Collections.ObjectModel
    Imports Prism.Mvvm
    Imports ClassLibrary1.Models
    
    Namespace ViewModels
    
        Public Class Window1ViewModel
            Inherits BindableBase
    
            Private _People As ObservableCollection(Of PersonModel)
            Public Property People() As ObservableCollection(Of PersonModel)
                Get
                    Return _People
                End Get
                Set(ByVal value As ObservableCollection(Of PersonModel))
                    _People = value
                End Set
            End Property
    
            ' コンストラクタ
            Public Sub New()
                Me.CreatePeople()
            End Sub
    
            Private Sub CreatePeople()
    
                Dim items = New List(Of PersonModel)
                For i As Integer = 0 To 10
                    items.Add(New PersonModel With
                              {
                              .FirstName = $"First {i}",
                              .LastName = $"Last {i}",
                              .Age = i
                              })
                Next
    
                Me.People = New ObservableCollection(Of PersonModel)(items)
    
            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"
            mc:Ignorable="d"
            Title="{Binding Title}" Height="350" Width="525">
    
        <DockPanel LastChildFill="True">
    
            <ListBox 
                DockPanel.Dock="Top"
                Name="listbox1" 
                ItemsSource="{Binding People}" />
            
            <!-- ListBox.SelectedItem 1つ分のバインドデータは、PersonModel 型になります -->
            <ContentControl
                prism:RegionManager.RegionName="DetailRegion"
                prism:RegionManager.RegionContext="{Binding ElementName=listbox1, Path=SelectedItem}" />
    
        </DockPanel>
    
    </Window>
    

  •  Bootstrapper.vb

  • Imports Microsoft.Practices.Unity
    Imports Prism.Unity
    Imports Prism.Modularity
    Imports WpfApplication1.Views
    Imports ClassLibrary1
    
    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
    
        ' モジュールカタログにモジュール情報を登録
        Protected Overrides Sub ConfigureModuleCatalog()
    
            Dim catalog = CType(Me.ModuleCatalog, ModuleCatalog)
            catalog.AddModule(GetType(ClassLibrary1Module))
    
        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