SourceChord

C#とXAML好きなプログラマの備忘録。最近はWPF系の話題が中心です。

添付ビヘイビアを作る

WPFSilverlightなどのプラットフォームで、昔からよく使われていたテクニックで添付ビヘイビアというものがあります。
この手法は、後にBlendSDKにも取り込まれ、Behaviorという共通の実装がSDKに導入されています。

ですが、ここはまず、自分で添付ビヘイビアを作ってみるところから始めてみたいと思います。
以下を参考にやってみました。
[WPF][C#]添付動作(AttachedBehavior)
M'sLabo report: 添付ビヘイビアでドラッグ&ドロップを簡単実装

添付ビヘイビアの作り方

添付ビヘイビアはザックリと以下3ステップで作れます。

  1. ビヘイビア定義用のクラスを作成する
  2. 添付プロパティを作成
    1. 「propa」と入力して、コードスニペットを使うと簡単に作成できます。
  3. 添付プロパティの変更イベントで、対象のコントロールに目的の処理を付加する
    1. 添付プロパティが設定された要素に対して、イベントの登録などを行う


ということで、マウス左ボタンを押したら、HelloWorldとメッセージボックスを表示する機能をコントロールに付加する、添付ビヘイビアを作ってみました。

HelloWorldBehavior.cs
    public class HelloWorldAttachedBehavior
    {
        public static bool GetShowMessage(DependencyObject obj)
        {
            return (bool)obj.GetValue(ShowMessageProperty);
        }

        public static void SetShowMessage(DependencyObject obj, bool value)
        {
            obj.SetValue(ShowMessageProperty, value);
        }

        // Using a DependencyProperty as the backing store for ShowMessage.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ShowMessageProperty =
            DependencyProperty.RegisterAttached("ShowMessage", typeof(bool), typeof(HelloWorldAttachedBehavior), new PropertyMetadata(false, OnShowMessageChanged));

        private static void OnShowMessageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var element = d as UIElement;
            if (element == null)
                return;

            var newValue = (bool)e.NewValue;
            if (newValue)
            {
                element.MouseLeftButtonDown += element_MouseLeftButtonDown;
            }
            else
            {
                element.MouseLeftButtonDown -= element_MouseLeftButtonDown;
            }
        }

        static void element_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            MessageBox.Show("Hello World!!");
        }
    }

使い方

対象のコントロールに、以下のように添付プロパティとして設定を行えばOK

MainWindow.xaml
<Window x:Class="AttachedBehaviorTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:AttachedBehaviorTest"
        Title="MainWindow"
        Width="525"
        Height="350">
    <Grid>
        <Rectangle Width="137"
                   Height="69"
                   Margin="10,10,0,0"
                   HorizontalAlignment="Left"
                   VerticalAlignment="Top"
                   Fill="#FFF4F4F5"
                   Stroke="Black"
                   local:HelloWorldAttachedBehavior.ShowMessage="True" />
        <TextBlock Margin="10,107,0,0"
                   HorizontalAlignment="Left"
                   VerticalAlignment="Top"
                   Text="TextBlock"
                   TextWrapping="Wrap"
                   local:HelloWorldAttachedBehavior.ShowMessage="True" />
    </Grid>
</Window>


Rectangleとか、TextBlockをクリックするとメッセージボックスが表示されるようになります。
f:id:minami_SC:20140315171614p:plain:w300

こういう作りなら、複数のコントロール間で使いまわす動作をスッキリと実装できそう。
添付ビヘイビアって便利ですね!!