Windows 8.1 RTM + Visual Studio 2013 RCの段階での情報です。
TriggerBehaviorには必ず以下のようなActionsプロパティが必要になります。
publicstaticreadonly DependencyProperty ActionsProperty = DependencyProperty.Register("Actions", typeof(ActionCollection), typeof(HogehogeTriggerBehavior), new PropertyMetadata(null)); public ActionCollection Actions { get { var actions = (ActionCollection)GetValue(ActionsProperty); if (actions == null) { actions = new ActionCollection(); this.SetValue(ActionsProperty, actions); } return actions; } }
毎回実装するのがめんどくさいので、という理由で基本クラスにまとめるという発想が出てくるので、以下のようなクラスを実装します。
using Microsoft.Xaml.Interactivity; using Windows.UI.Xaml; namespace App11 { publicclass TriggerBehaviorBase : DependencyObject, IBehavior { // 毎回実装するのもめんどくさいし、基本クラスで定義しておきますか。publicstaticreadonly DependencyProperty ActionsProperty = DependencyProperty.Register( "Actions", typeof(ActionCollection), typeof(TriggerBehaviorBase), new PropertyMetadata(null)); public ActionCollection Actions { get { var value = (ActionCollection)this.GetValue(ActionsProperty); if (value == null) { value = new ActionCollection(); this.SetValue(ActionsProperty, value); } returnvalue; } } // ついでだし、既存のビヘイビアっぽく実装できるようにしただけで、今回の本題ではない。public DependencyObject AssociatedObject { get; private set; } publicvoid Attach(DependencyObject associatedObject) { this.AssociatedObject = associatedObject; this.OnAttached(); } publicvoid Detach() { this.OnDetaching(); this.AssociatedObject = null; } protectedvirtualvoid OnAttached() { } protectedvirtualvoid OnDetaching() { } } }
こうしておけば、TriggerBehaviorの実装も楽になります。例えばボタンのクリックをトリガーにする場合は以下のような感じです。あぁ楽ちん。
using Microsoft.Xaml.Interactivity; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace App11 { publicclass ButtonClickTriggerBehavior : TriggerBehaviorBase { protectedoverridevoid OnAttached() { var btn = (Button)this.AssociatedObject; btn.Click += this.ButtonClick; } protectedoverridevoid OnDetaching() { var btn = (Button)this.AssociatedObject; btn.Click -= this.ButtonClick; } privatevoid ButtonClick(object sender, RoutedEventArgs e) { Interaction.ExecuteActions(this, this.Actions, e); } } }
落とし穴
このTriggerBehaviorに、ActionをBlendからドロップしようとしてもできません。以下のようになります。
Actionsプロパティは存在するので、プロパティウィンドウからコレクションエディタを使ってActionを追加できますが、これじゃぁ快適に開発できません。
解決策?(いまいちすぎる…)
とりあえず、TriggerBehaviorクラス自身(親ではなく自分自身)にActionsという名前のプロパティがあればActionをドロップできるみたいなので、newなりなんなりを使って強引にでも定義してやればドロップできるようになります。
using Microsoft.Xaml.Interactivity; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace App11 { publicclass ButtonClickTriggerBehavior : TriggerBehaviorBase { /// <summary>/// えっ・・・。/// </summary>publicnew ActionCollection Actions { get { returnbase.Actions; } } protectedoverridevoid OnAttached() { var btn = (Button)this.AssociatedObject; btn.Click += this.ButtonClick; } protectedoverridevoid OnDetaching() { var btn = (Button)this.AssociatedObject; btn.Click -= this.ButtonClick; } privatevoid ButtonClick(object sender, RoutedEventArgs e) { Interaction.ExecuteActions(this, this.Actions, e); } } }
これでプロジェクトをリビルドするとデザイナからぽとぺたでActionを追加できるようになります。
でも、Actionsプロパティが2個表示されて、とってもイマイチな見た目になってしまいます。
ううむ…。