WPF > 依存関係プロパティ


※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

コントロールを自作する場合に、コントロールが公開するプロパティは依存関係プロパティとして実装します。
依存関係プロパティとして実装すると、バインディングが使えるようになります。

  • リソース
  • データ バインディング
  • スタイル
  • 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);
		}
	}
}

参考サイト

読んでいる本


Effective C#

QLOOKアクセス解析

ここを編集