カスタムのトリガーとアクションの作成 (Blend SDK for WPF)

Triggers と Actions は因果関係にあります。 Trigger は原因に反応し、1 つ以上の Actions を呼び出します。

Trigger の作成

Trigger は、イベントの発生やプロパティの特定値への変更をなどの特定の状況をリッスンして、1 つ以上の関連づけられている Actions を呼び出すオブジェクトです。 Triggers の種類は、マウスまたはキーボード イベントが発生したときに Action を起動する EventTrigger から、2 つのオブジェクトが相反したときに Action を起動する CollisionTrigger まで多岐にわたります。 Triggers は拡張可能であるため、独自のカスタム トリガーを自由に作成することができます。 実行時に Behaviors で認識されるようにするためには、Trigger に一定の基本構文を含める必要があります。

以下に挙げるコード サンプルは、基本的な Trigger の例です。

public class Trigger1 : TriggerBase<DependencyObject>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        // Insert code that you want to run when the Trigger is attached to an object.
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        // Insert code that you want to run when the Trigger is removed from an object.
    }

    //
    // To invoke any associated Actions when this Trigger gets called, use
    // this.InvokeActions(o), where o is an object that you can pass in as a parameter.
    //
}

上記のコード例では、クラスは System.Windows.Interactivity.dll で提供される種類である、TriggerBase から拡張されています。 クラスが TriggerBase クラスから拡張されると、コード例で示されるように、OnAttached メソッドと OnDetaching メソッドをオーバーライドできます。

OnDetaching は、Trigger とその AssociatedObject との関連付けが解除される直前に呼び出されます。 つまり、Trigger のスコープ内でオブジェクトは依然として利用可能であり、OnDetaching の終了時 (たとえば、イベント ハンドラーのフックを解除する等) までコードで対応できるということです。

Trigger に関わる最も重要な作業は、それを実際に起動させることです。 Trigger を起動させるには、InvokeActions メソッドを呼び出す必要があります。 InvokeActions が呼び出されると、この Trigger に関連付けられたすべての Actions を実行するよう通知されます。

Action の作成

Trigger は、何かが起こるまで "リッスンする" オブジェクトです。 Action は、何かを "する" オブジェクトです。

以下に挙げるコード サンプルは、基本的な Action の例です。

public class MyAction : TriggerAction<DependencyObject>
{
    public MyAction()
    {
        // Insert code required for object creation below this point.
    }

    protected override void Invoke(object o)
    {
        // Insert code that defines what the Action will do when it is triggered or invoked.
    }
}

Trigger によって Invoke メソッドが呼び出されるため、Action で実行するコードは、Invoke メソッドから何らかの形でアクセスできるようにする必要があります。 以下に挙げるコード サンプルは、呼び出されたときに MessageBox を表示する Action の例です。

public class ShowMessageBoxAction : TriggerAction<DependencyObject>
{
    public string Message
    {
        get { return (string)GetValue(MessageProperty); }
        set { SetValue(MessageProperty, value); }
    }

    public static readonly DependencyProperty MessageProperty = DependencyProperty.Register("Message", typeof(string), typeof(ShowMessageBoxAction), new PropertyMetadata(""));

    public ShowMessageBoxAction()
    {
        // Insert code required for object creation below this point.
    }

    protected override void Invoke(object o)
    {
        MessageBox.Show(Message);
    }
}

上記のコード サンプルの Action は、前述の単純な Action よりは複雑ですが、Action を発生させる共通の特性は変わっていません。 ShowMessageBoxAction は、TriggerAction から拡張されており、Invoke メソッドを上書きします。

要素の対象化

Action の対象を変更することは可能ですが、既定では、Action はそれにアタッチされた要素である AssociatedObject プロパティにしかアクセスできません。 Action の対象を別の要素に変更するには、Action のクラスを TriggerAction ではなく、TargetedTriggerAction から拡張します。

public class MyAction : TargetedTriggerAction<DependencyObject>
{
    // See TriggerAction in the preceding code sample...
}

クラスを TargetedTriggerAction から拡張すると、TargetName および Target プロパティを使用して、対象となる要素にアクセスできるようになります。 AssociatedObject は、Action が現在関連付けられている要素を指定するため、AssociatedObject と TargetName または Target プロパティを代替しないでください。

参照

概念

カスタム ビヘイビアーの作成 (Blend SDK for WPF)