かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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));

過去記事