サーチ…


前書き

依存関係プロパティは、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は、 FrameworkElementControlなどの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));
}

プロパティー名、プロパティータイプ、クラスのタイプ、デフォルト値の更新など、必要な変更を加えるには、コードスニペットのさまざまな部分をタブで選択する必要があります。

重要な慣習

ここにはいくつかの重要な慣習/規則があります。

  1. 依存関係プロパティのCLRプロパティを作成します。このプロパティは、オブジェクトのコードビハインドや他のコンシューマによって使用されます。 GetValueSetValueを呼び出して、コンシューマには必要ないようにする必要があります。

  2. 依存関係プロパティに正しく名前を付けます。 DependencyPropertyフィールドはpublic static readonly必要がありpublic static readonly 。 CLRプロパティ名に対応し、 TextTextPropertyなどの "Property"で終わる名前を持つ必要がありTextProperty

  3. 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=TwoWayTextBox.Textの動作に類似)を指定する必要性を排除するには、 PropertyMetadata代わりにFrameworkPropertyMetadataを使用し、適切なフラグを指定するようにコードを更新します。

public static readonly DependencyProperty MyPropertyProperty =
    DependencyProperty.Register("MyProperty", typeof(int), typeof(MyControl), 
        new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

添付された依存プロパティ

いつ使用するか

添付プロパティは、プロパティの存在を認識しているさまざまなコントロールまたはサービスの動作を強化するために、 DependencyObjectに適用できる依存プロパティです。

添付プロパティのユースケースには、次のものがあります。

  1. 親要素を持つことで、その子要素を繰り返し、特定の方法で子要素に作用します。たとえば、 Gridコントロールは、 Grid.RowGrid.ColumnGrid.RowSpan 、およびGrid.ColumnSpan添付プロパティを使用して、要素を行と列に配置します。
  2. カスタムテンプレートを使用して既存のコントロールにビジュアルを追加しTextBox 。たとえば、空のテキストボックスにウォーターマークを追加するには、 TextBoxをサブクラス化する必要がありません。
  3. ToolTipServiceFocusManagerなどの既存のコントロールの一部またはすべてに汎用サービスまたは機能を提供する。これらは、一般に、 接続された動作と呼ばれます
  4. 継承がダウンすると、例えば、 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は、対応するGetRowSetRowメソッドがありGetRow

警告

MSDNで文書化されているように

プロパティ値の継承は、非添付の依存関係プロパティに対して機能するように見えるかもしれませんが、ランタイムツリー内の特定の要素境界を介した非関連付けプロパティの継承動作は定義されていません。常にメタデータに継承を指定する場合は、プロパティを登録するためにRegisterAttachedを使用してください。

読み取り専用の依存関係プロパティ

いつ使用するか

読み取り専用の依存関係プロパティは、通常の依存関係プロパティと似ていますが、コントロールの外側からその値を設定できないように構成されています。これは、 IsMouseOverIsKeyboardFocusWithinなど、消費者にとって純粋に情報的なプロパティを持っている場合にうまく機能します。

定義方法

標準の依存関係プロパティと同様に、読み取り専用の依存関係プロパティは、 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つの重要な違いがあります。

  1. DependencyPropertyprivate DependencyPropertyKeyから供給されます。
  2. CLRプロパティ設定ツールはpublicではなくprotectedまたはprivateです。

MyPropertyPropertyは、 MyPropertyPropertyMyPropertyPropertyKeyMyPropertyPropertySetValueメソッドにMyPropertyPropertyないことに注意してください。プロパティは読み取り専用で定義されているため、プロパティでSetValueを使用しようとすると、 DependencyPropertyKeyを受け取るオーバーロードで使用する必要があります。それ以外の場合は、 InvalidOperationExceptionがスローされます。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow