サーチ…
前書き
依存関係プロパティは、CLRプロパティを拡張するプロパティの一種です。 CLRプロパティはクラスのメンバーから直接読み込まれますが、GetValue()メソッドを呼び出すと、Dependencyプロパティが動的に解決され、オブジェクトは基本のDependencyObjectクラスからの継承を介して取得されます。
このセクションでは、Dependency Propertiesを分解し、概念的にもコード例でもその使用方法を説明します。
構文
- DependencyProperty.Register(文字列名、タイプpropertyType、タイプownerType)
- DependencyProperty.Register(文字列名、型propertyType、型ownerType、PropertyMetadata型メタデータ)
- DependencyProperty.Register(文字列名、タイプpropertyType、タイプownerType、PropertyMetadata typeMetadata、ValidateValueCallback validateValueCallback)
- DependencyProperty.RegisterAttached(文字列名、型propertyType、型ownerType)
- DependencyProperty.RegisterAttached(文字列名、型propertyType、型ownerType、PropertyMetadata型メタデータ)
- DependencyProperty.RegisterAttached(文字列名、型propertyType、型ownerType、PropertyMetadata typeMetadata、ValidateValueCallback validateValueCallback)
- DependencyProperty.RegisterReadOnly(文字列名、型propertyType、型ownerType、PropertyMetadata型メタデータ)
- DependencyProperty.RegisterReadOnly(文字列名、型propertyType、型ownerType、PropertyMetadata型メタデータ、ValidateValueCallback validateValueCallback)
- DependencyProperty.RegisterAttachedReadOnly(文字列名、タイプpropertyType、タイプownerType、PropertyMetadata typeMetadata)
- DependencyProperty.RegisterAttachedReadOnly(文字列名、タイプpropertyType、タイプownerType、PropertyMetadata typeMetadata、ValidateValueCallback validateValueCallback)
パラメーター
パラメータ | 詳細 |
---|---|
名 | プロパティ名のString 表現 |
物件のタイプ | プロパティのType 。たとえば、 typeof(int) |
ownerType | プロパティが定義されているクラスのType です。たとえば、 typeof(MyControl) またはtypeof(MyAttachedProperties) です。 |
typeMetadata | インスタンスSystem.Windows.PropertyMetadata デフォルト値を定義する(またはそのサブクラスの1つ)は、プロパティがコールバックを変え、 FrameworkPropertyMetadata 様結合オプションを定義することができSystem.Windows.Data.BindingMode.TwoWay 。 |
validateValueCallback | プロパティの新しい値が有効な場合はtrueを、そうでない場合はfalseを返すカスタムコールバック。 |
標準依存プロパティ
いつ使用するか
実質的にすべてのWPFコントロールは、依存プロパティを頻繁に使用します。依存関係プロパティでは、スタイル、アニメーション、データバインディング、値継承、および変更通知のサポートを含むがこれに限定されない、標準のCLRプロパティでは不可能な多くのWPF機能を使用できます。
TextBox.Text
プロパティは、標準の依存関係プロパティが必要な場所の簡単な例です。ここで、 Text
が標準のCLRプロパティであった場合、データバインディングは不可能です。
<TextBox Text="{Binding FirstName}" />
定義方法
DependencyPropertiesは、 FrameworkElement
、 Control
などのDependencyObject
から派生したクラスでのみ定義できます。
構文を覚えることなく標準の依存関係プロパティを作成する最も速い方法の1つは、 propdp
と入力してTabキーを押して、 "propdp"スニペットを使用することです。必要に応じて変更できるコードスニペットが挿入されます。
public class MyControl : Control
{
public int MyProperty
{
get { return (int)GetValue(MyPropertyProperty); }
set { SetValue(MyPropertyProperty, value); }
}
// Using a DependencyProperty as the backing store for MyProperty.
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(int), typeof(MyControl),
new PropertyMetadata(0));
}
プロパティー名、プロパティータイプ、クラスのタイプ、デフォルト値の更新など、必要な変更を加えるには、コードスニペットのさまざまな部分をタブで選択する必要があります。
重要な慣習
ここにはいくつかの重要な慣習/規則があります。
依存関係プロパティのCLRプロパティを作成します。このプロパティは、オブジェクトのコードビハインドや他のコンシューマによって使用されます。
GetValue
とSetValue
を呼び出して、コンシューマには必要ないようにする必要があります。依存関係プロパティに正しく名前を付けます。
DependencyProperty
フィールドはpublic static readonly
必要がありpublic static readonly
。 CLRプロパティ名に対応し、Text
やTextProperty
などの "Property"で終わる名前を持つ必要がありTextProperty
。CLRプロパティのセッターにロジックを追加しないでください。依存関係プロパティシステム(とXAMLは特に)はCLRプロパティを使用しません。プロパティーの値が変更されたときにアクションを実行する場合は、
PropertyMetadata
を介してコールバックを提供する必要があります。public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register("MyProperty", typeof(int), typeof(MyControl), new PropertyMetadata(0, MyPropertyChangedHandler)); private static void MyPropertyChangedHandler(DependencyObject sender, DependencyPropertyChangedEventArgs args) { // Use args.OldValue and args.NewValue here as needed. // sender is the object whose property changed. // Some unboxing required. }
バインドモード
バインドでMode=TwoWay
( TextBox.Text
の動作に類似)を指定する必要性を排除するには、 PropertyMetadata
代わりにFrameworkPropertyMetadata
を使用し、適切なフラグを指定するようにコードを更新します。
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(int), typeof(MyControl),
new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
添付された依存プロパティ
いつ使用するか
添付プロパティは、プロパティの存在を認識しているさまざまなコントロールまたはサービスの動作を強化するために、 DependencyObject
に適用できる依存プロパティです。
添付プロパティのユースケースには、次のものがあります。
- 親要素を持つことで、その子要素を繰り返し、特定の方法で子要素に作用します。たとえば、
Grid
コントロールは、Grid.Row
、Grid.Column
、Grid.RowSpan
、およびGrid.ColumnSpan
添付プロパティを使用して、要素を行と列に配置します。 - カスタムテンプレートを使用して既存のコントロールにビジュアルを追加し
TextBox
。たとえば、空のテキストボックスにウォーターマークを追加するには、TextBox
をサブクラス化する必要がありません。 -
ToolTipService
やFocusManager
などの既存のコントロールの一部またはすべてに汎用サービスまたは機能を提供する。これらは、一般に、 接続された動作と呼ばれます 。 - 継承がダウンすると、例えば、
DataContext
の動作と同様に、ビジュアルツリーが必要になります。
これは、 Grid
ユースケースで何が起こっているかをさらに示しています。
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Your Name:" />
<TextBox Grid.Column="1" Text="{Binding FirstName}" />
</Grid>
Grid.Column
は、 Label
またはTextBox
いずれかに存在するプロパティではありません。むしろ、 Grid
コントロールはその子要素を調べて、添付されたプロパティの値に従って並べます。
定義方法
この例では、引き続きGrid
を使用します。以下にGrid.Column
の定義を示しますが、簡潔にするためにDependencyPropertyChangedEventHandler
は除外されています。
public static readonly DependencyProperty RowProperty =
DependencyProperty.RegisterAttached("Row", typeof(int), typeof(Grid),
new FrameworkPropertyMetadata(0, ...));
public static void SetRow(UIElement element, int value)
{
if (element == null)
throw new ArgumentNullException("element");
element.SetValue(RowProperty, value);
}
public static int GetRow(UIElement element)
{
if (element == null)
throw new ArgumentNullException("element");
return ((int)element.GetValue(RowProperty));
}
添付されたプロパティはさまざまなアイテムに添付できるため、CLRプロパティとして実装することはできません。代わりに静的メソッドのペアが導入されています。
したがって、標準の依存プロパティとは対照的に、 DependencyObject
から派生していないクラスでは、接続プロパティを定義することもできます。
依存プロパティRowProperty
は、対応するGetRow
とSetRow
メソッドがありGetRow
。
警告
プロパティ値の継承は、非添付の依存関係プロパティに対して機能するように見えるかもしれませんが、ランタイムツリー内の特定の要素境界を介した非関連付けプロパティの継承動作は定義されていません。常にメタデータに継承を指定する場合は、プロパティを登録するためにRegisterAttachedを使用してください。
読み取り専用の依存関係プロパティ
いつ使用するか
読み取り専用の依存関係プロパティは、通常の依存関係プロパティと似ていますが、コントロールの外側からその値を設定できないように構成されています。これは、 IsMouseOver
やIsKeyboardFocusWithin
など、消費者にとって純粋に情報的なプロパティを持っている場合にうまく機能します。
定義方法
標準の依存関係プロパティと同様に、読み取り専用の依存関係プロパティは、 DependencyObject
から派生したクラスで定義する必要があります。
public class MyControl : Control
{
private static readonly DependencyPropertyKey MyPropertyPropertyKey =
DependencyProperty.RegisterReadOnly("MyProperty", typeof(int), typeof(MyControl),
new FrameworkPropertyMetadata(0));
public static readonly DependencyProperty MyPropertyProperty = MyPropertyPropertyKey.DependencyProperty;
public int MyProperty
{
get { return (int)GetValue(MyPropertyProperty); }
private set { SetValue(MyPropertyPropertyKey, value); }
}
}
通常の依存関係プロパティに適用されるのと同じ規則がここでも適用されますが、2つの重要な違いがあります。
-
DependencyProperty
はprivate
DependencyPropertyKey
から供給されます。 - CLRプロパティ設定ツールは
public
ではなくprotected
またはprivate
です。
MyPropertyProperty
は、 MyPropertyProperty
をMyPropertyPropertyKey
、 MyPropertyProperty
はSetValue
メソッドにMyPropertyProperty
ないことに注意してください。プロパティは読み取り専用で定義されているため、プロパティでSetValue
を使用しようとすると、 DependencyPropertyKey
を受け取るオーバーロードで使用する必要があります。それ以外の場合は、 InvalidOperationException
がスローされます。