はじめに
こんにちは、吉原です。WPFを学習していて、理解に時間のかかった依存関係プロパティについて備忘録として残しておきたいと思います。
依存関係プロパティとは
依存関係プロパティとは、WPFにおいて通常のプロパティを拡張し、データバインディング、スタイルなどをサポートする仕組みです。プロパティの値は、コードに直接設定された値、スタイル、バインディングなど、複数の要素から値を設定できます。また、プロパティの値が変更されると、自動的にUIに反映することができるため、再描画等の手間を軽減できます。
既存のWPFコントロールにはない、独自の依存関係プロパティを設計することで、UIの柔軟性、拡張性を向上させることが可能となります。
依存関係プロパティの作成
依存関係プロパティは、DependencyProperty.Registerメソッドを使用します。その際に以下の情報が必要となります。
DependencyProperty.Register(
"プロパティ名", // プロパティ名(文字列)
typeof(プロパティの型), // プロパティのデータ型
typeof(登録するクラス), // 登録するクラス
... // その他メタデータ
);
ここで登録するクラスとは、WPFが依存関係プロパティをクラス単位で管理しているため、この依存関係プロパティが「どのクラスが持つプロパティなのか」を明確にするために指定するモノです。別のクラスで使用したい場合は、DependencyProperty.AddOwnerメソッドで使用可能となります。
次にその他メタデータとは、メタデータで主に設定できるのは以下です。
- デフォルト値:プロパティが初期化されていない場合にデフォルト値を設定
- コールバック関数:プロパティの値が変更された時に呼び出されるコールバック関数の設定
- 値の強制:無効な値の設定の抑制
- バインディング値の動作設定:バインディングの方向や更新モードの設定
これらは、PropertyMetadataを使用した場合ですが、FrameworkPropertyMetadataを使用すれば、さらに詳細に設定することが可能です。
CLRラッパー
依存関係プロパティを登録した際に、忘れてはいけないのがこのCLRラッパーです。簡単にいうと、登録した依存関係プロパティを通常のプロパティのように扱えるようにする操作です。
そもそもCLR(Commmon Language Runtime)とは、.NET対応のプログラムの実行環境を提供するランタイムのことです。そんなCLRが提供する標準的な機能を用いて定義されたものが通常のプロパティ(CLRプロパティ)です。
依存関係プロパティは通常のプロパティとは異なるため、直接的に GetValue や SetValue メソッドを呼び出して値を取得・設定する必要があります。
そこで、開発者が通常のプロパティのように簡単に使えるようにするために行う操作がCLRラッパーです。これにより、プロパティの値の取得・設定時に GetValue と SetValue の呼び出しを内部で処理し、依存関係プロパティへのアクセスが簡単になります。
public class MyControl : Control
{
// 依存関係プロパティの登録
public static readonly DependencyProperty IsHighlightedProperty =
DependencyProperty.Register(
"IsHighlighted", // プロパティ名
typeof(bool), // プロパティの型
typeof(MyControl), // 登録するクラス
new PropertyMetadata(false) // デフォルト値
);
// CLRラッパー(通常のプロパティと同様に扱う)
public bool IsHighlighted
{
get { return (bool)GetValue(IsHighlightedProperty); }
set { SetValue(IsHighlightedProperty, value); }
}
}
おわりに
以上の理解で私は依存プロパティを理解し実装できるようになりました。また、この記事を書くことによって、より自分の理解が確かなものへと変わったという実感が湧きました。今後も、学習や業務を通して躓いた点や大事な点があった際に、積極的に投稿していきたいと思います。