日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。XAMLDispatcherObjectの1段下に継承階層をおりると、DependencyObjectというクラスになります。DependencyObjectは、WPFで使われた独自のプロパティシステムを実装しています。この独自のプロパティシステムのことを、依存関係プロパティと添付プロパティといいます。存関係プロパティ依存関係プロパティは、通常のCLRのプロパティと比べて、以下の機能を追加で提供します。依存関係プロパティは、DependencyObjectを直接、または間接的に継承したクラスで定義可能です。定義方法は、DependencyPropertyクラスのRegisterメソッドを使用します。DependencyObjectを継承したPersonクラスにNameという依存関係プロパティを定義する方法を以下に示します。ここではデフォルト値を設定してる}Registerメソッドを使いDependencyPropertyクラスのインスタンスを作成します。readonlyのフィールドに「プロパティ名Property」の命名規約で格納します。DependencyPropertyの値は、DependencyObjectクラスに定義されているGetValue、SetValueメソッドで取得と設定が可能です。上記クラスを使ってName依存関係プロパティの値の取得と設定をするコード例を以下に示します。値を取得Console.WriteLine(p.GetValue(Person.NameProperty));実行すると、以下のような出力になります。nameおおたGetValueメソッドとSetValueメソッドを使って依存関係プロパティの値の取得と設定が出来ますが、通常のプロパティの使用方法とかけ離れているため、通常は、以下のようなCLRのプロパティのラッパーを作成します。}}上記のプロパティを使うと使用する側のコードは自然なC#によるクラスを利用したコードになります。"おおた";Console.WriteLine(p.Name);デフォルト値の設定Personクラスの例で示したように、依存関係プロパティは、メタデータを使ってでデフォルト値の設定が出来ます。デフォルト値は、全てのクラスで同じインスタンスが使われます。このようにして、大量のインスタンスが生成されたときにメモリをデフォルト値によって無駄に使うことがないようになっています。その反面、List型などのような参照型の値の場合同じインスタンスを使うと不都合があるケースがあります。先ほどのPersonクラスにChildrenというList型の依存関係プロパティを追加してデフォルト値にList型のインスタンスを指定したとします。}}このようにすると、2つのPersonクラスのインスタンスを作った時に、Childrenプロパティの値が共有されて不都合がおきてしまいます。p2.Children.Count);このプログラムの実行結果はどちらも2が表示されてしまいます。このような問題を避けるためには、通常のプロパティと同じように、デフォルト値をコンストラクタで行う必要があります。List<Person>();}これで問題は起きなくなります。依存関係プロパティのメタデータには、第二引数にプロパティの値に変更があったときに呼ばれるコールバックメソッドを指定することが出来ます。以下のように設定をします。e.NewValue);}DependencyPropertyChangedEventArgsのOldValueプロパティとNewValueプロパティで変更前、変更後の値の取得が可能です。プロパティの値が変わった時に何か処理をしたいときに使用します。注意点としては、staticメソッドで、値が変更されたインスタンスはメソッドの引数にDependencyObjectの形で渡されるという点です。値が変更されたインスタンスに何か操作をしたい場合は、引数で渡されたものをキャストして使用します。依存関係プロパティには、値が有効範囲にあるかどうかを指定する方法があります。メタデータの第三引数にcoerceValueCallbackという引数を指定することで、値がプロパティにとって正しい範囲にあるかを検証する処理を追加することができます。以下にPersonクラスにAgeというプロパティを追加して、値の範囲が0~120であるように矯正する処理を設定している例を示します。Console.WriteLine("Ageプロパティが{0}から{1}に変わりました。}}CoerceAgeValueメソッドが値を矯正している処理になります。範囲外の値が設定された場合は、範囲内の値を返しています。この処理がどのように動くか示すためのコードを以下に示します。150;実行結果は以下のようになります。Ageプロパティが0から10に変わりました。Ageプロパティが10から0に変わりました。Ageプロパティが0から120に変わりました。-10を設定したのに0が設定されていることと、150を設定したのに120が設定されていることが確認できます。この値の矯正処理は、プロパティの変更時だけではなくDependencyObjectのCoerceValueメソッドに依存関係プロパティを渡すことでも呼び出すことができます。使われる例として、最大値(Maximum)と最小値(Minimum)を指定できるクラスで、このプロパティの値が変わった時にthis.CoerceValue(ValuePeoperty);のように値のプロパティを最大値と最小値の範囲内に矯正する処理を呼び出すといったケースがあります。プロパティの妥当性検証プロパティの値の矯正の他に、不正な値が設定されたときに例外をスローする検証処理を記述する方法も提供されています。これはメタデータではなく、Registerメソッドの第5引数として指定します。値を受け取り、その値が妥当な値の場合はtrueを返し、不正な値の場合はfalseを返すようにします。AgeプロパティがMinValue、MaxValueの場合に不正な値とするコード例を以下に示します。int.MinValue;}このようにすると、以下のようにMaxValueやMinValueを設定するとArgumentExceptionの例外がスローされます。「WPFのイベントシステム」WPFは、イベントも独自の機構を構築しています。C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。Blogの内容は個人の見解であり、所属する企業を代表するものではありません。)はてなブログをはじめよう!okazukiさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。