かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

WPF4.5入門 その45 「添付プロパティ」

添付プロパティは、別のDependencyObjectを継承したクラスに対して、任意のプロパティを設定することが出来る機能です。例えば、GridクラスのRow添付プロパティやColumn添付プロパティがあります。これは、Grid内の別コントロールに対して、何行目、何列目に表示するのかを設定するのに使用します。注目すべきなのは、Row添付プロパティとColumn添付プロパティはButtonなどには定義されていませんが、Buttonなどの様々なコントロールに設定可能な点です。これが添付プロパティの特徴になります。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <!-- Grid.Row添付プロパティの設定例 -->
    <Button Grid.Row="0" Content="Button1" />
    <Button Grid.Row="1" Content="Button2" />
</Grid>

添付プロパティを定義する方法は、基本的に依存関係プロパティと同じような流れになります。コード例を以下に示します。

public static class Sample
{
    // RegisterAttachedメソッドを使って添付プロパティを作成する
    public static readonly DependencyProperty BirthdayProperty =
        DependencyProperty.RegisterAttached(
            "Birthday", 
            typeof(DateTime), 
            typeof(Sample), 
            new PropertyMetadata(DateTime.MinValue));
}

依存関係プロパティがRegisterメソッドを使っていたのに対して添付プロパティは、RegisterAttachメソッドを使用します。メソッドの引数は基本的にRegisterメソッドと同じです。添付プロパティのもう1つの特徴として、定義するクラス自体にはDependencyObjectクラスの継承は必要ないという点があります。添付プロパティを設定するクラス側でDependencyObjectクラスを継承していれば問題ありません。

添付プロパティの値の取得や設定も、依存関係プロパティと同様にGetValueメソッドとSetValueメソッドを使って行います。

// 依存関係プロパティと同様にSetValue、GetValueで値の設定を取得が可能
var p = new Person();
p.SetValue(Sample.BirthdayProperty, DateTime.Now);
Console.WriteLine(p.GetValue(Sample.BirthdayProperty));

GetValueメソッドとSetValueメソッドを使って値の取得や設定を行うのは、非現実的なため、通常は添付プロパティを定義したクラスにGetプロパティ名、Setプロパティ名という名前の静的メソッドを定義します。上記のBirthday添付プロパティの完全な定義を以下に示します。

public static class Sample
{
    // RegisterAttachedメソッドを使って添付プロパティを作成する
    public static readonly DependencyProperty BirthdayProperty =
        DependencyProperty.RegisterAttached(
            "Birthday", 
            typeof(DateTime), 
            typeof(Sample), 
            new PropertyMetadata(DateTime.MinValue));

    // プログラムからアクセスするための添付プロパティのラッパー
    public static DateTime GetBirthday(DependencyObject obj)
    {
        return (DateTime)obj.GetValue(BirthdayProperty);
    }

    public static void SetBirthday(DependencyObject obj, DateTime value)
    {
        obj.SetValue(BirthdayProperty, value);
    }
}

このメソッドを使うと、添付プロパティを使うコードは以下のようになります。

// 通常はラッパーを使ってアクセスする
var p = new Person();
Sample.SetBirthday(p, DateTime.Now);
Console.WriteLine(Sample.GetBirthday(p));

過去記事