VB のたまご

作成日: 2017/03/20, 更新日: 2017/03/20



トリガーとアクション

  •  (※もし、直接このページにたどり着いた方は、以前投稿した Livetアプリケーション作成時の注意 を読んで、 名前空間やプロジェクト追加に気を付ける必要があることを知ってください)

  • スポンサーリンク


  •  トリガーとアクションは、ビヘイビアを分割しただけのものです。つまり、ビヘイビアと、トリガー+アクションは同じ機能です。 ビヘイビアでは、コントロールとイベント、そしてイベントハンドラを書きました。 このうち、コントロールとイベントだけを管理するのがトリガーで、実際の処理だけを管理するのがアクションとなります。

  •  それではよく分からなくていいので、サンプルを見てみましょう。 以下では、「Livet WPF4.5 MVVM アプリケーション」で作成しています。

  •  このサンプルでは、トリガーもアクションもソースは、「Behaviors」フォルダを作成してその中に作成しました。 どちらも専用のテンプレートファイルは無いため、「クラス」を作成して以下を書きます。

  •  それでは、トリガークラス、アクションクラスの順に作ってみましょう。

  • Imports System.Windows.Interactivity
    
    Namespace Behaviors
    
        ' Button に機能をアタッチ(取り付け)、デタッチ(取り外し)
        ' Click イベントにより、任意の処理を実行する(この部分はトリガーアクション側に委託する)
        ' 継承時に任意の型を指定することで、継承元メンバーの AssociatedObject の型が決まる
        ' AssociatedObject を指定のコントロールと見立てて操作する
        ' Associate(アソシエイト) は「関連した、結びついた」というような意味合い
        Public Class ButtonClickTrigger
            Inherits TriggerBase(Of Button)
    
            ' Button にアタッチしたときの処理(イベント登録)
            Protected Overrides Sub OnAttached()
                MyBase.OnAttached()
    
                AddHandler Me.AssociatedObject.Click, AddressOf Me.Button_Click
    
            End Sub
    
            ' Button からデタッチしたときの処理(イベント解除)
            Protected Overrides Sub OnDetaching()
    
                RemoveHandler Me.AssociatedObject.Click, AddressOf Me.Button_Click
    
                MyBase.OnDetaching()
            End Sub
    
            ' 実際の処理は、トリガーアクションに委託
            Private Sub Button_Click(sender As Object, e As EventArgs)
    
                Me.InvokeActions(e)
    
            End Sub
    
        End Class
    End Namespace
    

    Imports System.Windows.Interactivity
    
    Namespace Behaviors
        Public Class HelloAction
            Inherits TriggerAction(Of Button)
    
            Protected Overrides Sub Invoke(parameter As Object)
    
                ' 特に意味は無い処理。Parameter にはイベント引数が入ってくる
                Dim e = TryCast(parameter, EventArgs)
                If e Is Nothing Then
    
                End If
    
                Console.WriteLine("Hello, InteractionTrigger And TriggerAction!")
    
            End Sub
        End Class
    
    End Namespace
    

  •  処理の説明は、前回のビヘイビアと同じです。

  •  トリガーは、System.Windows.Interactivity 名前空間にある TriggerBase(Of T) クラスから継承して作成します。 トリガーの処理は、振る舞いはクリックイベントを利用して、アクションを呼び出すように委託しています。 「取り付け」と「取り外し」に該当するのが、それぞれ「OnAttached」メソッドと「OnDetaching」メソッドです。 基本的に、ここには、「コントロールのイベント」と、「対応するイベントハンドラ」を追加、または解除する処理を書きます。 ここではクリックイベントを追加、または解除しています。

  •  アクションは、System.Windows.Interactivity 名前空間にある TriggerAction(Of T) クラスから継承して作成します。 アクションの処理は、イベントハンドラ内の処理でそのままです。

  • スポンサーリンク


  •  次に、このトリガーとアクションを使ってみましょう。以下はそのサンプルです。

  • <Window x:Class="Views.TriggerAndActionWindow1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
            xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
            xmlns:v="clr-namespace:w09_Interactions.Views"
            xmlns:vm="clr-namespace:w09_Interactions.ViewModels"
            xmlns:b="clr-namespace:w09_Interactions.Behaviors"
            Title="TriggerAndActionWindow1" Height="350" Width="525">
        
         <i:Interaction.Triggers>
         
            <!--WindowのContentRenderedイベントのタイミングでViewModelのInitializeメソッドが呼ばれます-->
            <i:EventTrigger EventName="ContentRendered">
                <l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="Initialize"/>
            </i:EventTrigger>
    
            <!--Windowが閉じたタイミングでViewModelのDisposeメソッドが呼ばれます-->
            <i:EventTrigger EventName="Closed">
                <l:DataContextDisposeAction/>
            </i:EventTrigger>
    
        </i:Interaction.Triggers>
    
        <StackPanel Margin="10">
    
            <Button Content="トリガーとアクションのテスト">
                <i:Interaction.Triggers>
                    <b:ButtonClickTrigger>
                        <b:HelloAction />
                    </b:ButtonClickTrigger>
                </i:Interaction.Triggers>
            </Button>
    
            <!-- 組み込みトリガーの EventTrigger と自作アクションの組み合わせ -->
            <!-- トリガーとアクションは独立したものなので、組み合わせて使うことができる -->
            <!-- ビヘイビアはトリガーとアクションが合わさったものなので、固定処理したい時に使う -->
            <Button Content="トリガーとアクションのテスト2">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseDoubleClick">
                        <b:HelloAction />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
    
        </StackPanel>
        
    </Window>
    

  •  Window.DataContext プロパティに、ViewModels の TriggerAndActionWindow1ViewModel をセットするように記載されていますが、 ここでは、バインドしたいデータは無いので(ビューモデルは不要なので)、このタグ一式をコメントアウト、または削除してしまいます。 こうすると、TriggerAndActionWindow1ViewModel.vb を作成せずともビルドを通すことができます。

  •  Window タグ内の名前空間定義の中に「xmlns:b="clr-namespace:w09_Interactions.Behaviors"」と追記しました。 ViewModels の1行をコピペして、フォルダ名に該当する名前空間だけ Behaviros に変更したものです。 プレフィックス(接頭辞、v や vm の部分)は何でもいいですが、ここでは「b」としています。 Button タグの下に、Interaction.Behaviors タグを書いて、この中に作成したビヘイビアを書きます。

  •  できたら実行して動作確認してみましょう。 1つ目のボタンはクリックすることで文字列が出力されます。2つ目のボタンはダブルクリックすることで文字列が出力されます。 トリガーとアクションは、ビヘイビアと違って2つに分かれているので、組み合わせて使うことができます。