かずきのBlog@hatena

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

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クラスのインスタンスを外部に公開すると、読み取り専用ではなくなってしまうため実装するさいは注意をして行ってください。

過去記事