property)」という、通常のプロパティ(区別のために、WPFの文脈においては「CLRプロパティ」と呼ぶことがある)とは異なる「値の保持機構」を持っている。親要素で設定した値をそのまま継承して使うための機構。1カ所で定義したオブジェクトを複数カ所から参照するための、リソースの定義/参照機構。HTMLでいうところのCSSのようなスタイル設定機構。モデルとビューの間など、異なるオブジェクト間で値を結び付ける(一方での値の変更を他方に通知し、即座に反映させる)機構。依存関係プロパティの用途これらは、いずれも「ほかの要素の値に依存してプロパティの値を決定する機構」といえる。依存関係プロパティという名前はここから来ている。リソース、スタイル、および、データ・バインディングに関する詳細は次回以降で説明する。今回は、依存関係プロパティの定義および利用方法について説明していく(包含継承の説明を含む)。5に、依存関係プロパティを定義するクラスの最低限の実装例を示す。依存関係プロパティを定義する最低限のクラス定義(上:C#、下:VB)依存関係プロパティの定義には、DependencyPropertyクラス(System.Windows名前空間)を用いる。DependencyPropertyクラスのインスタンス自身は、プロパティそのものというよりは辞書のキーのようなもので、実際に値を保持するのはDependencyObjectクラス(System.Windows名前空間)(の子クラス)になる。依存関係プロパティの定義(C#)実際の値の読み書きはDependencyObjectクラスのSetValue/GetValueメソッドを通して行う。内部的にSetValue/GetValueメソッドを呼び出すだけのCLRプロパティ(この例の場合、Xプロパティ)も定義しておく。このCLRプロパティ内ではSetValue/GetValueメソッド呼び出し以外の処理を行ってはならない。依存関係プロパティは、必ずしもこのCLRプロパティを通して呼ばれるわけではなく、データ・バインディングなどを行うとSetValue/GetValueメソッドが直接呼び出される場合があるため、CLRプロパティ内に記述した処理は行われないことがある。依存関係プロパティの仕組みは、添付プロパティを実現するためにも利用される。6に示すように、Registerメソッドの代わりにRegisterAttachedメソッドを用いた登録を行う。添付プロパティとして利用する場合の依存関係プロパティの登録(上:C#、下:VB)また、添付プロパティの場合には、CLRプロパティの代わりに「Setプロパティ名」「Getプロパティ名」(上記のコードの例では「GetX」「SetX」)という名前の静的メソッドを定義しておく。通常の依存関係プロパティの場合と同様、これらのSet/Getメソッドの内部では、DependencyObject.SetValue/DependencyObject.GetValueメソッド呼び出し以外の処理を行ってはならない。●オーナー・クラスの追加ほかのクラスで定義された既存の依存関係プロパティを自作のクラスでも利用したい場合、DependencyProperty.AddOwnerメソッドを用いることで、WPFに登録情報を追加できる。7に示すような記述を行う。依存関係プロパティのオーナー・クラスの追加(上:C#、下:VB)この仕組みは例えば、ComboBoxクラス(System.Windows.Controls名前空間)などのIsSelected依存関係プロパティなどで利用されている。IsSelected="true"/>」と書くことができる。●依存関係プロパティの意義WPFが、CLRプロパティではなく、わざわざ依存関係プロパティのような仕組みを利用する意義は、以下のような点にある。(1)パフォーマンス依存関係プロパティは一種の辞書構造になっているが、これはデータ・バインディングのパフォーマンスの向上や、添付プロパティの実現のために利用されている。CLRプロパティを用いてデータ・バインディングのような仕組みを実現するためには、リフレクションに頼ることになる。一般に、リフレクションの利用は著しくパフォーマンスを低下させることがある。プロパティの値を辞書的に持てば、リフレクションの利用を避けることができ、パフォーマンスの向上が見込める。辞書的に値を持つことで、添付プロパティ(=要素自身ではなく、親要素で利用する値を保持する機構)も実現可能である。依存関係プロパティは、次節で説明するようなメタデータを持つことができる。●メタデータメタデータはPropertyMetadataクラス(System.Windows名前空間)、もしくは、その子クラスのインスタンスとして定義する。利用場面に応じて以下の3つのうちのいずれかを用いる(いずれもSystem.Windows名前空間に所属するクラス)。PropertyMetadataクラスUIPropertyMetadataクラスFrameworkPropertyMetadataクラスPropertyMetadataクラスは、WPFに限らず幅広い用途で利用することを想定したもので、メタデータとして最低限の情報を持っている。PropertyMetadataクラスの持っているプロパティのうち、主要なものを以下に示す。依存関係プロパティのデフォルト値。(このプロパティは)依存関係プロパティの値を変更する前に呼び出され、値が適切かどうかを判定し、適切でなければ適切な値に修正するためのコールバック・メソッド。このような挙動を「値の強制(coercion)」と呼ぶ。(このプロパティは)依存関係プロパティの値が変更された際に呼び出されるコールバック・メソッド。UIPropertyMetadataクラスは、UI要素向けのメタデータで、PropertyMetadataクラスの持つ情報に加えて、アニメーションの可否を表すIsAnimationProhibitedプロパティを持つ。FrameworkPropertyMetadataクラスは、WPF用のメタデータで、UIPropertyMetadataクラスの持つ情報に加えて、WPF固有の豊富な機能向けの情報を持っている。FrameworkPropertyMetadataクラスのプロパティのうち、主要なものを以下に示す。値の包含継承が行われるかどうか。データ・バインディングに対応しているかどうか。データ・バインディングの既定の挙動が双方向であることを示す。依存関係プロパティを利用する際、包含継承やスタイルなどを併用すると、複数の個所から値が設定されることになる。この場合、値の設定元には優先順位があり、順位の高いものが依存関係プロパティの値に反映される。優先順位は以下のとおりである(上に行くほど優先度が高い)。PropertyMetadataクラスのCoerceValueCallbackプロパティに設定したコールバック・メソッドによる値の強制アニメーションによる動的な値の更新ローカル値(=要素に対して直接設定した値)TemplatedParent(=テンプレート親。最後に、ルーティング・イベントについて解説する。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。