VB のたまご

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



ViewModelLocator4

  •  今度は、View があるプロジェクトと ViewModel があるプロジェクトが分かれている環境下で、ViewModel をバインドします。 モジュールの分割構成が、レイヤー分けされている場合の時とか用ですね。

  • スポンサーリンク


  •  この場合も、前回と同じように、ブートストラッパー内で、ConfigureViewModelLocator メソッドに、独自名前解決ルールを定義します。

  •  同じく、ViewModelLocationProvider クラスの SetDefaultViewTypeToViewModelTypeResolver メソッドを使って、名前解決リゾルバメソッドを定義します。

  •  ただ、名前解決リゾルバメソッドは、ViewModel があるプロジェクト側で準備しておき、ブートストラッパーでは、このリゾルバを参照するようにします。

  •  以下は、ViewModel があるプロジェクトで作成したリゾルバクラスです。 ここでの名前解決方法は、名前空間は ViewModel があるプロジェクトの名前空間と、View クラス名に ViewModel を付けた名前を合わせて、 ViewModel の名前空間を作成します。後は型として返却するだけです。

  • Public Class CustomViewTypeToViewModelTypeResolver
    
        Public Shared Function Resolve(viewType As Type) As Type
    
            If viewType Is Nothing Then
                Throw New ArgumentNullException("viewType is Nothing")
            End If
    
            Dim resolverType = GetType(CustomViewTypeToViewModelTypeResolver)
            Dim viewModelNamespace = $"{resolverType.Namespace}.ViewModels"
            Dim viewModelName = $"{viewModelNamespace}.{viewType.Name}ViewModel"
            Return resolverType.Assembly.GetType(viewModelName)
    
        End Function
    
    End Class
    

  •  ブートストラッパーではこのクラスを参照するように命令します。

  • Protected Overrides Sub ConfigureViewModelLocator()
        MyBase.ConfigureViewModelLocator()
    
        ' 別 プロジェクト内にある ViewModel を指定したいので、対象プロジェクト先に作成した名前解決リゾルバにお任せする
        ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver(AddressOf CustomViewTypeToViewModelTypeResolver.Resolve)
    
    End Sub
    

  •  このサンプルを実行すると、ViewModel の値が画面表示されます。

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

  •  ViewModel があるプロジェクト

  •  Window1ViewModel.vb

  • Namespace ViewModels
    
        Public Class Window1ViewModel
    
            Public Property Title As String = "Prism Unity Application"
    
        End Class
    
    End Namespace
    

  •  CustomViewTypeToViewModelTypeResolver.vb

  • Imports System.Reflection
    
    Public Class CustomViewTypeToViewModelTypeResolver
    
        Public Shared Function Resolve(viewType As Type) As Type
    
            If viewType Is Nothing Then
                Throw New ArgumentNullException("viewType is Nothing")
            End If
    
            Dim resolverType = GetType(CustomViewTypeToViewModelTypeResolver)
            Dim viewModelNamespace = $"{resolverType.Namespace}.ViewModels"
            Dim viewModelName = $"{viewModelNamespace}.{viewType.Name}ViewModel"
            Return resolverType.Assembly.GetType(viewModelName)
    
        End Function
    
    End Class
    

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

  •  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">
    
        <Grid>
            <TextBlock Text="{Binding Title}" FontSize="40" />
        </Grid>
    
    </Window>
    

  •  Bootstrapper.vb

  • Imports Microsoft.Practices.Unity
    Imports Prism.Unity
    Imports Prism.Mvvm
    Imports WpfApplication1.Views
    Imports System.Reflection
    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
    
        ' ViewModelLocator の VM 探し(名前空間解決)方法をカスタマイズ
        Protected Overrides Sub ConfigureViewModelLocator()
            MyBase.ConfigureViewModelLocator()
    
            ' 別 プロジェクト内にある ViewModel を指定したいので、対象プロジェクト先に作成した名前解決リゾルバにお任せする
            ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver(AddressOf CustomViewTypeToViewModelTypeResolver.Resolve)
    
        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