VB のたまご

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



CustomNotificationRequest

  •  続いては、情報系メッセージ(戻り値を気にしない)を「独自に作成した画面」で表示する方法を学習します。

  • スポンサーリンク


  •  この場合、View で表示したい UserControl を作成して、View で待ち構えている InteractionRequestTrigger タグ内で、 独自画面を表示するように指定するだけで、メッセージボックスから独自画面へ、差し替えることができるようになります。 ViewModel には、前回と全く同じ呼び出し方をするだけです。

  •  それでは、コードを見ていきましょう。 まずは、画面を呼び出す処理からです。ViewModel には情報メッセージボックスを表示した時と同じように記載します。

  • Public Property RequestMessage As InteractionRequest(Of INotification)
    Public Property RequestCommand As DelegateCommand
    
    ' コンストラクタ
    Public Sub New()
    
        Me.RequestMessage = New InteractionRequest(Of INotification)
        Me.RequestCommand = New DelegateCommand(AddressOf Me.ShowMessage)
    
    End Sub
    
    Private Sub ShowMessage()
    
        Dim message = New Notification With {.Title = "カスタム画面の通知", .Content = "カスタム画面の通知メッセージです"}
        Me.RequestMessage.Raise(message, AddressOf Me.ShowMessageCallback)
    
    End Sub
    
    Private Sub ShowMessageCallback(message As INotification)
        Me.Title = "カスタム画面でした"
    End Sub
    

  •  続いて、View 側です。
  •  トリガーアクションで、PopupWindowAction アクションを呼び出す際、WindowContent プロパティに表示したい UserControl 名を指定します。

  • <i:Interaction.Triggers>
    
        <prism:InteractionRequestTrigger SourceObject="{Binding RequestMessage}">
            <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True">
                <prism:PopupWindowAction.WindowContent>
                    <local:CustomView />
                </prism:PopupWindowAction.WindowContent>
            </prism:PopupWindowAction>
        </prism:InteractionRequestTrigger>
    
    </i:Interaction.Triggers>
    

  •  最後に、カスタム画面です。何かの表示文言と閉じるボタンがあればそれっぽく見えることと思います。 ここでは、バインドさせる ViewModel が重要なポイントになります。 メッセージボックスの代わりとして動作させるため、IInteractionRequestAware インターフェースを実装します。 これを継承していると、インスタンス生成時に、Notification プロパティと FinishInteraction プロパティに対して、インスタンスがインジェクションされます。

  •  Notification プロパティは、ViewModel で呼び出し時に作成した、メッセージ文言のクラスインスタンスがセットされます。 FinishInteraction プロパティは、画面を閉じるためのアクションがセットされています。 ここではそれぞれ、画面に表示させたり、ボタンのコマンド処理として使っています。

  • Public Class CustomViewModel
        Inherits BindableBase
        Implements IInteractionRequestAware
    
        Public Property CloseCommand As DelegateCommand
    
        Private _Notification As INotification
        Public Property Notification As INotification Implements IInteractionRequestAware.Notification
            Get
                Return _Notification
            End Get
            Set(value As INotification)
                Me.SetProperty(_Notification, value)
            End Set
        End Property
    
        Private _FinishInteraction As Action
        Public Property FinishInteraction As Action Implements IInteractionRequestAware.FinishInteraction
            Get
                Return _FinishInteraction
            End Get
            Set(value As Action)
                Me.SetProperty(_FinishInteraction, value)
            End Set
        End Property
    
        ' コンストラクタの後で、Action プロパティと INotification プロパティにインジェクションされる
        ' コンストラクタ・インジェクションしていないし Dependency 属性も付けていないが、インジェクションされるみたい
        Public Sub New()
    
            Me.CloseCommand = New DelegateCommand(AddressOf Me.Close)
    
        End Sub
    
        Private Sub Close()
    
            Me.FinishInteraction?.Invoke()
    
        End Sub
    
    End Class
    

  •  このサンプルを実行すると、ボタンが表示されるのでボタンを押すと、独自に作成した画面が表示されます。 ボタンを押すことで画面を閉じることができます。

  • スポンサーリンク


  •  それでは、以下ソース全体です。
  •  今回は、WPF アプリケーションプロジェクトだけです。

  •  CustomViewModel.vb

  • Imports Prism.Mvvm
    Imports Prism.Commands
    Imports Prism.Interactivity.InteractionRequest
    
    Namespace ViewModels
    
        Public Class CustomViewModel
            Inherits BindableBase
            Implements IInteractionRequestAware
    
            Public Property CloseCommand As DelegateCommand
    
            Private _Notification As INotification
            Public Property Notification As INotification Implements IInteractionRequestAware.Notification
                Get
                    Return _Notification
                End Get
                Set(value As INotification)
                    Me.SetProperty(_Notification, value)
                End Set
            End Property
    
            Private _FinishInteraction As Action
            Public Property FinishInteraction As Action Implements IInteractionRequestAware.FinishInteraction
                Get
                    Return _FinishInteraction
                End Get
                Set(value As Action)
                    Me.SetProperty(_FinishInteraction, value)
                End Set
            End Property
    
            ' コンストラクタの後で、Action プロパティと INotification プロパティにインジェクションされる
            ' コンストラクタ・インジェクションしていないし Dependency 属性も付けていないが、インジェクションされるみたい
            Public Sub New()
    
                Me.CloseCommand = New DelegateCommand(AddressOf Me.Close)
    
            End Sub
    
            Private Sub Close()
    
                Me.FinishInteraction?.Invoke()
    
            End Sub
    
        End Class
    
    End Namespace
    

  •  Window1ViewModel.vb

  • Imports Prism.Mvvm
    Imports Prism.Commands
    Imports Prism.Interactivity.InteractionRequest
    
    Namespace ViewModels
    
        ' 独自画面も同じように、ViewModel で InteractionRequest クラスの準備(依頼の指示)、
        ' View で InteractionRequestTrigger トリガー&アクションを準備(依頼された画面の表示)して、
        ' 2つの組み合わせで表示します
    
        Public Class Window1ViewModel
            Inherits BindableBase
    
            Private _Title As String
            Public Property Title() As String
                Get
                    Return _Title
                End Get
                Set(ByVal value As String)
                    Me.SetProperty(_Title, value)
                End Set
            End Property
    
            Public Property RequestMessage As InteractionRequest(Of INotification)
            Public Property RequestCommand As DelegateCommand
    
            ' コンストラクタ
            Public Sub New()
    
                Me.Title = "Prism Unity Application"
                Me.RequestMessage = New InteractionRequest(Of INotification)
                Me.RequestCommand = New DelegateCommand(AddressOf Me.ShowMessage)
    
            End Sub
    
            Private Sub ShowMessage()
    
                Dim message = New Notification With {.Title = "カスタム画面の通知", .Content = "カスタム画面の通知メッセージです"}
                Me.RequestMessage.Raise(message, AddressOf Me.ShowMessageCallback)
    
            End Sub
    
            Private Sub ShowMessageCallback(message As INotification)
                Me.Title = "カスタム画面でした"
            End Sub
    
        End Class
    
    End Namespace
    

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

  • <UserControl x:Class="Views.CustomView"
                 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"
                 xmlns:prism="http://prismlibrary.com/"
                 prism:ViewModelLocator.AutoWireViewModel="True"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
    
        <StackPanel>
    
            <TextBlock Text="{Binding Notification.Title}" />
            <TextBlock Text="{Binding Notification.Content}" />
            <Button Content="OK" Command="{Binding CloseCommand}" />
    
        </StackPanel>
        
    </UserControl>
    

  •  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">
    
        <!-- 要求を受けて、通知メッセージを表示する。モーダル形式の表示方法で、親画面の中央に表示する -->
        <i:Interaction.Triggers>
    
            <prism:InteractionRequestTrigger SourceObject="{Binding RequestMessage}">
                <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True">
                    <prism:PopupWindowAction.WindowContent>
                        <local:CustomView />
                    </prism:PopupWindowAction.WindowContent>
                </prism:PopupWindowAction>
            </prism:InteractionRequestTrigger>
    
        </i:Interaction.Triggers>
    
        <!-- 画面 -->
        <StackPanel>
    
            <Button Content="button1" Command="{Binding RequestCommand}" />
            <TextBlock Text="{Binding Title}" />
    
        </StackPanel>
    
    </Window>
    

  •  Bootstrapper.vb

  • Imports Microsoft.Practices.Unity
    Imports Prism.Unity
    Imports Prism.Modularity
    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
    
    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