依存関係プロパティ
最終更新:
atachi
コントロールを自作する場合に、コントロールが公開するプロパティは依存関係プロパティとして実装します。
依存関係プロパティとして実装すると、バインディングが使えるようになります。
- リソース
- データ バインディング
- スタイル
- Animations
- メタデータのオーバーライド
- プロパティ値の継承
- WPF デザイナーの統合
依存関係プロパティの基本実装
依存関係プロパティは次のようにDependencyPropertyを使用して値を管理します。
値の取得や設定はすべてGetValueメソッド/SetValueメソッドで行われます。
コントロールを使う側は、公開されているプロパティである依存関係プロパティだけしか見えません。
class MyCustomControl : Control {
// 依存関係プロパティの識別子
public static readonly DependencyProperty IsSpinningProperty =
DependencyProperty.Register(
"IsSpinning", // name 引数
typeof(Boolean), // propertyType 引数
typeof(MyCustomControl), // ownerType 引数
);
// 依存関係プロパティ
public bool IsSpinning {
get { return (bool)GetValue(IsSpinningProperty); }
set { SetValue(IsSpinningProperty, value); }
}
}
依存関係プロパティの識別子を実装
DependencyProperty.Register()を使用して、 WPFが持つプロパティシステムにプロパティに関する情報を登録します。
引数名 | 設定内容例 | 説明 |
name | "IsSpinning" | プロパティシステムに登録するプロパティ名。 |
propertyType | typeof(Boolean) | プロパティの型情報。typeofを使って型情報を取り出す。 |
ownerType | typeof(MyCustomControl) | プロパティを定義したクラスの型情報。 |
typeMetadata | new FrameworkPropertyMetadata(...) |
プロパティについての追加情報。 FrameworkPropertyMetadata を使って指定する。省略可能。 こちら |
validateValueCallback | new ValidateValueCallback(...) |
プロパティの値についてのバリデーション。 ValidateValueCallback を使って指定する。省略可能。 |
Registerの戻り値には依存関係プロパティに関する情報が含まれている。
依存関係プロパティに値を設定する場合や取得する場合はこのインスタンスをつかって行う。
このインスタンスは、public static readonlyで定義する必要がある。
FrameworkPropertyMetadataで指定するメタデータについて
FrameworkPropertyMetadata を使用すると、プロパティに関する設定が行える。
- プロパティの初期値
- プロパティ変更時に呼び出されるコールバックメソッド
- WPFデザイナによるデザイン時の挙動
- デフォルトのデータバインディングのモード
- VisualObjectツリーで親から子へのプロパティ継承
WPFデザイナに関係するプロパティがいくつかあります。
適切に設定することで、WPFデザイナ使用時のパフォーマンスがよくなります。
-
AffectsMeasure
プロパティ値の変更時に、サイズ変更を伴うコントロールの再描画が必要。 -
AffectsArrange
プロパティ値の変更時に、サイズ変更を伴わない(自分より下階層のサイズ変更は許可)コントロールの再描画が必要。 -
AffectsRender
プロパティ値の変更時に、一切のサイズ変更が伴われないコントロールの再描画が必要。
コレクションの依存関係プロパティ
- カスタムコントロールのコンストラクタでSetValueを使ってsingletonなコレクション型インスタンスを作成する
- 依存関係プロパティ識別子は読み取り専用で登録する(DependencyProperty.RegisterReadOnly を使用する)
class MyCustomControl : Control {
public MyCustomControl() : base() {
SetValue(ItemsPropertyKey, new List<FrameworkElement>() );
}
private static readonly DependencyPropertyKey ItemsPropertyKey =
DependencyProperty.RegisterReadOnly(
"Items",
typeof(List<FrameworkElement>),
typeof(MyCustomControl),
new FrameworkPropertyMetadata(new List<FrameworkElement>())
);
// 依存関係プロパティの識別子
public static readonly DependencyProperty IsSpinningProperty =
DependencyProperty.Register(
"IsSpinning", // name 引数
typeof(Boolean), // propertyType 引数
typeof(MyCustomControl), // ownerType 引数
);
public static readonly DependencyProperty ItemsProperty = ItemsPropertyKey.DependencyProperty;
// 依存関係プロパティ
public bool IsSpinning {
get { return (bool)GetValue(IsSpinningProperty); }
set { SetValue(IsSpinningProperty, value); }
}
public List<FrameworkElement> Items {
get {
return (List<FrameworkElement>)GetValue(ItemsProperty);
}
}
}