かずきのBlog@hatena

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

WPF4.5入門 その43 「読み取り専用の依存関係プロパティ」

これまで見てきた依存関係プロパティは全て読み書きできるものでしたが、読み取り専用の依存関係プロパティも定義できます。読み取り専用の依存関係プロパティは、DependencyPropertyKeyというクラスを使用します。

読み取り専用の依存関係プロパティの例を以下に示します。

// RegisterReadOnlyメソッドでDependencyPropertyKeyを取得
private static readonly DependencyPropertyKey BirthdayPropertyKey =
    DependencyProperty.RegisterReadOnly(
        "Birthday",
        typeof(DateTime),
        typeof(Person),
        new PropertyMetadata(DateTime.Now));
// DependencyPropertyは、DependencyPropertyKeyから取得する
public static readonly DependencyProperty BirthdayProperty = BirthdayPropertyKey.DependencyProperty;

public DateTime Birthday
{
    // getは従来通り
    get { return (DateTime)GetValue(BirthdayProperty); }
    // setはDependencyPropertyKeyを使って行う
    private set { SetValue(BirthdayPropertyKey, value); }
}

コメントにある通り、DependencyPropertyKeyクラスのインスタンスはDependencyPropertyクラスのRegisterReadOnlyメソッドを使って取得します。このDependencyPropertyKeyクラスのインスタンスは、外部に公開しないように管理します。

DependencyPropertyのインスタンスは、DependencyPropertyKeyクラスのDependencyPropertyプロパティを使って取得します。これは、普通の依存関係プロパティと同じようにpublic static readonlyのフィールドで管理します。あとは、GetValueメソッドとSetValueメソッドを使ったCLRのプロパティのラッパーを作るのですが、このときSetValueではDependencyPropertyKeyのインスタンスを使って設定を行います。DependencyPropertyクラスのインスタンスを使うと例外が発生するので注意してください。また、プロパティのsetterは、読み取り専用の依存関係プロパティでは外部に公開しないように管理します。

このように、値の取得には内部で管理しているDependencyPropertyKeyクラスのインスタンスを使うようにすることで読み取り専用の依存関係プロパティを実現します。DependencyPropertyKeyクラスのインスタンスを外部に公開すると、読み取り専用ではなくなってしまうため実装するさいは注意をして行ってください。

過去記事