VB のたまご

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



CompositeCommand

  •  ここでは、CompositeCommand(コンポジットコマンド、複合コマンド)について学習します。 CompositeCommand は、DelegateCommand をまとめて扱うコマンドです。コマンドを扱うコマンドですね。

  • スポンサーリンク


  •  ちょっとイメージが湧かないかもしれないので、先に使い方を見てみましょう。 Hello1, Hello2 は実行処理(Execute)メソッド、CanHello1, CanHello2 は実行可否処理(CanExecute)メソッド、 HelloText1, HelloText2 プロパティは文字列です。

  • Public Property HelloCommand1 As DelegateCommand
    Public Property HelloCommand2 As DelegateCommand
    Public Property AllCommand As CompositeCommand
    
    ' コンストラクタ
    Public Sub New()
    
        Me.HelloCommand1 = New DelegateCommand(AddressOf Me.Hello1, AddressOf Me.CanHello1)
        Me.HelloCommand1.ObservesProperty(Function() Me.HelloText1)
    
        Me.HelloCommand2 = New DelegateCommand(AddressOf Me.Hello2, AddressOf Me.CanHello2)
        Me.HelloCommand2.ObservesProperty(Function() Me.HelloText2)
    
        ' RegisterCommand メソッドで任意のコマンドを登録します。
        ' 登録した全てのコマンドが実行可能になった時に、CompositeCommand も実行可能になります。
        ' 実行処理は、全てのコマンドの実行です。
        Me.AllCommand = New CompositeCommand
        Me.AllCommand.RegisterCommand(Me.HelloCommand1)
        Me.AllCommand.RegisterCommand(Me.HelloCommand2)
    
        '' 解除したい場合は、UnregisterCommand メソッドで任意のコマンドを指定します。
        'Me.AllCommand.UnregisterCommand(Me.HelloCommand1)
        'Me.AllCommand.UnregisterCommand(Me.HelloCommand2)
    
    End Sub
    

  •  HelloText1 プロパティを監視する HelloCommand1 コマンド、HelloText2 プロパティを監視する HelloCommand2 コマンドがあります。 さらに、HelloCommand1 コマンド、HelloCommand2 コマンドを監視する AllCommand コマンドがあります。

  •  この状態の AllCommand コマンドは、HelloCommand1 コマンドと HelloCommand2 コマンドの両方が実行可能な場合のみ、AllCommand も実行可能になります。 同様に AllCommand コマンドを実行すると、HelloCommand1 コマンドの実行と HelloCommand2 コマンドの実行の両方を行います。

  • AllCommand の CanExecute() は、
    AllCommand.CanExecute() = HelloCommand1.CanExecute() AndAlso HelloCommand2.CanExecute()
    
    AllCommand の Execute() は、
    AllCommand.Execute() = HelloCommand1.Execute() を実行した後で、HelloCommand2.Execute() を実行
    

  •  となります。 2つのコマンドを一緒に扱って(複合、コンポジット)、実行するコマンドということですね。

  •  このサンプルを実行すると、入力欄が2つあり、両方とも入力すると、最後のボタンを押せるようになります。 どちらかの入力欄が空欄になると、最後のボタンが押せなくなります。

  •  最後のボタンを押すと、1つ目の入力欄にある文字列の出力(1つ目のボタンのコマンド)、 2つ目の入力欄にある文字列の出力(2つ目のボタンのコマンド)が行われます。

  • スポンサーリンク


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

  •  Window1ViewModel.vb

  • Imports Prism.Mvvm
    Imports Prism.Commands
    
    Namespace ViewModels
    
        Public Class Window1ViewModel
            Inherits BindableBase
    
            ' CompositeCommand は、DelegateCommand をまとめて扱うコマンド。
            ' (Composite、コンポジット、複合)
    
            Private _HelloText1 As String
            Public Property HelloText1() As String
                Get
                    Return _HelloText1
                End Get
                Set(ByVal value As String)
                    Me.SetProperty(_HelloText1, value)
                End Set
            End Property
    
            Private _HelloText2 As String
            Public Property HelloText2() As String
                Get
                    Return _HelloText2
                End Get
                Set(ByVal value As String)
                    Me.SetProperty(_HelloText2, value)
                End Set
            End Property
    
            Public Property HelloCommand1 As DelegateCommand
            Public Property HelloCommand2 As DelegateCommand
            Public Property AllCommand As CompositeCommand
    
            ' コンストラクタ
            Public Sub New()
    
                Me.HelloCommand1 = New DelegateCommand(AddressOf Me.Hello1, AddressOf Me.CanHello1)
                Me.HelloCommand1.ObservesProperty(Function() Me.HelloText1)
    
                Me.HelloCommand2 = New DelegateCommand(AddressOf Me.Hello2, AddressOf Me.CanHello2)
                Me.HelloCommand2.ObservesProperty(Function() Me.HelloText2)
    
                ' RegisterCommand メソッドで任意のコマンドを登録します。
                ' 登録した全てのコマンドが実行可能になった時に、CompositeCommand も実行可能になります。
                ' 実行処理は、全てのコマンドの実行です。
                Me.AllCommand = New CompositeCommand
                Me.AllCommand.RegisterCommand(Me.HelloCommand1)
                Me.AllCommand.RegisterCommand(Me.HelloCommand2)
    
                '' 解除したい場合は、UnregisterCommand メソッドで任意のコマンドを指定します。
                'Me.AllCommand.UnregisterCommand(Me.HelloCommand1)
                'Me.AllCommand.UnregisterCommand(Me.HelloCommand2)
    
            End Sub
    
            ' 実行処理1
            Private Sub Hello1()
    
                Debug.WriteLine($"{Me.HelloText1}")
    
            End Sub
    
            ' 実行可否処理1
            Private Function CanHello1() As Boolean
    
                Return Not String.IsNullOrWhiteSpace(Me.HelloText1)
    
            End Function
    
            ' 実行処理2
            Private Sub Hello2()
    
                Debug.WriteLine($"{Me.HelloText2}")
    
            End Sub
    
            ' 実行可否処理2
            Private Function CanHello2() As Boolean
    
                Return Not String.IsNullOrWhiteSpace(Me.HelloText2)
    
            End Function
    
        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="Window1" Height="350" Width="525">
    
        <StackPanel>
    
            <StackPanel Margin="30">
                <TextBox Text="{Binding HelloText1, UpdateSourceTrigger=PropertyChanged}" />
                <Button Content="button1" Command="{Binding HelloCommand1}" />
            </StackPanel>
    
            <StackPanel Margin="30">
                <TextBox Text="{Binding HelloText2, UpdateSourceTrigger=PropertyChanged}" />
                <Button Content="button2" Command="{Binding HelloCommand2}" />
            </StackPanel>
    
            <StackPanel Margin="30">
                <Button Content="button3" Command="{Binding AllCommand}" />
            </StackPanel>
    
        </StackPanel>
    
    </Window>
    

  •  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
    
    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