VB のたまご

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



EventAggregator2

  •  引き続き、EventAggregator です。 今回は、イベント受信側が、無条件で受信するのではなく、条件一致したイベントデータのみ受信できるように、フィルタ機能を学習します。

  • Private Aggregator As IEventAggregator
    
    Public Sub New(_aggregator As IEventAggregator)
    
        Me.Aggregator = _aggregator
        Me.Messages = New ObservableCollection(Of String)
    
        ' 「MessageSentEvent」からのメッセージを受信(イベント受信)
        ' ただし何でも受信するのではなく、メッセージに「Prism」という文字列が含まれているもののみにフィルタする
        Me.Aggregator.GetEvent(Of MessageSentEvent)().Subscribe(
            Sub(x) Me.Messages.Add(x),
            ThreadOption.PublisherThread,
            False,
            Function(x) x.Contains("Prism"))
    
    End Sub
    

  •  Subscribe メソッドにはオーバーロードがあり、第二引数に動作するスレッドの種類、 第三引数に、購読を保持しておくか(自分で破棄処理を書くか)、第四引数に、フィルタ処理を記載します。

  •  このサンプルでは、渡されてきた文字列に対して、ある単語が含まれているかどうかで、受信を拒否するか受け入れるか判断しています。 これだけです。

  •  このサンプルを実行すると、前回と同じ画面が表示されますが、ボタンを押してもメッセージが送信されません。 これを送信できるようにするには、入力欄に入力された文字列の中に「Prism」という文字を含めることで、送信できるようになります。

  • スポンサーリンク


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

  •  最初に、共有イベントを関するプロジェクト(クラスライブラリ)です。

  •  MessageSentEvent.vb

  • Imports Prism.Events
    
    ' メッセージを送信する共通イベント
    Public Class MessageSentEvent
        Inherits PubSubEvent(Of String)
    
    End Class
    

  •  続いて、イベント送信するプロジェクト(クラスライブラリ)です。

  •  MessageViewModel.vb

  • Imports Microsoft.Practices.Unity
    Imports Prism.Commands
    Imports Prism.Events
    Imports Prism.Mvvm
    Imports WpfApplication1.Common
    
    Namespace ViewModels
    
        Public Class MessageViewModel
            Inherits BindableBase
    
            Private _Message As String = "メッセージを送信"
            Public Property Message() As String
                Get
                    Return _Message
                End Get
                Set(ByVal value As String)
                    Me.SetProperty(_Message, value)
                End Set
            End Property
    
            Public Property SendMessageCommand As DelegateCommand
    
            <Dependency>
            Public Property Aggregator As IEventAggregator
    
            Public Sub New()
    
                ' メッセージを送信するイベント「MessageSentEvent」としてメッセージを送信(イベント発信)
                Me.SendMessageCommand =
                    New DelegateCommand(Sub() Me.Aggregator.GetEvent(Of MessageSentEvent).Publish(Me.Message))
    
            End Sub
    
        End Class
    
    End Namespace
    

  •  MessageView.xaml
  •  画面クラスのコードビハインドには、名前空間の追加以外、処理はありません。

  • <UserControl x:Class="Views.MessageView"
                 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"
                 Padding="25">
    
        <StackPanel>
            <TextBlock Text="Left Region" Margin="5" />
            <TextBox Text="{Binding Message}" Margin="5" />
            <Button Command="{Binding SendMessageCommand}" Content="メッセージ送信" Margin="5" />
        </StackPanel>
        
    </UserControl>
    

  •  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("LeftRegion", GetType(MessageView))
    
        End Sub
    
    End Class
    

  •  続いて、イベント受信するプロジェクト(クラスライブラリ)です。

  •  MessageListViewModel.vb

  • Imports Prism.Events
    Imports Prism.Mvvm
    Imports System.Collections.ObjectModel
    Imports WpfApplication1.Common
    
    Namespace ViewModels
    
        Public Class MessageListViewModel
            Inherits BindableBase
    
            Private _Messages As ObservableCollection(Of String)
            Public Property Messages() As ObservableCollection(Of String)
                Get
                    Return _Messages
                End Get
                Set(ByVal value As ObservableCollection(Of String))
                    _Messages = value
                End Set
            End Property
    
            Private Aggregator As IEventAggregator
    
            Public Sub New(_aggregator As IEventAggregator)
    
                Me.Aggregator = _aggregator
                Me.Messages = New ObservableCollection(Of String)
    
                ' 「MessageSentEvent」からのメッセージを受信(イベント受信)
                ' ただし何でも受信するのではなく、メッセージに「Prism」という文字列が含まれているもののみにフィルタする
                Me.Aggregator.GetEvent(Of MessageSentEvent)().Subscribe(
                    Sub(x) Me.Messages.Add(x),
                    ThreadOption.PublisherThread,
                    False,
                    Function(x) x.Contains("Prism"))
    
            End Sub
    
        End Class
    
    End Namespace
    

  •  MessageList.xaml
  •  画面クラスのコードビハインドには、名前空間の追加以外、処理はありません。

  • <UserControl x:Class="Views.MessageList"
                 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:ClassLibrary2.Views"
                 xmlns:prism="http://prismlibrary.com/"
                 prism:ViewModelLocator.AutoWireViewModel="True"
                 Padding="25">
    
        <DockPanel LastChildFill="True">
            <TextBlock DockPanel.Dock="Top" Text="Right Region" Margin="5" />
            <ListBox ItemsSource="{Binding Messages}" />
        </DockPanel>
    
    </UserControl>
    

  •  ClassLibrary2Module.vb

  • Imports Prism.Modularity
    Imports Prism.Regions
    Imports ClassLibrary2.Views
    
    Public Class ClassLibrary2Module
        Implements IModule
    
        Private Manager As IRegionManager
    
        Public Sub New(_manager As IRegionManager)
            Me.Manager = _manager
        End Sub
    
        Public Sub Initialize() Implements IModule.Initialize
            Me.Manager.RegisterViewWithRegion("RightRegion", GetType(MessageList))
        End Sub
    
    End Class
    

  •  最後に、Shell を持つプロジェクト(WPF アプリケーション)です。

  •  Window1ViewModel.vb

  • Imports Prism.Mvvm
    
    Namespace ViewModels
    
        Public Class Window1ViewModel
            Inherits BindableBase
    
            Private _Title As String = "Prism Unity Application"
            Public Property Title() As String
                Get
                    Return _Title
                End Get
                Set(ByVal value As String)
                    _Title = value
                End Set
            End Property
    
        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">
    
        <Grid>
    
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
    
            <ContentControl
                Grid.Column="0"
                prism:RegionManager.RegionName="LeftRegion" />
    
            <ContentControl
                Grid.Column="1"
                prism:RegionManager.RegionName="RightRegion" />
    
        </Grid>
    
    </Window>
    

  •  Bootstrapper.vb

  • Imports Microsoft.Practices.Unity
    Imports Prism.Unity
    Imports Prism.Modularity
    Imports WpfApplication1.Views
    Imports ClassLibrary1
    Imports ClassLibrary2
    
    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))
            catalog.AddModule(GetType(ClassLibrary2Module))
    
        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