添付プロパティの概要 (WPF .NET)
添付プロパティは、拡張アプリケーション マークアップ言語 (XAML) の概念です。 添付プロパティを使用すると、DependencyObjectから派生するすべての XAML 要素に対して追加のプロパティと値のペアを設定できます。ただし、要素はオブジェクト モデルでそれらの追加のプロパティを定義していません。 追加のプロパティには、グローバルにアクセスできます。 添付プロパティは、通常、従来のプロパティ ラッパーを持たない特殊な形式の依存関係プロパティとして定義されます。
前提 条件
この記事では、依存関係プロパティの基本的な知識と、依存関係プロパティの概要
添付プロパティを使用する理由
添付プロパティを使用すると、子要素は、親要素で定義されているプロパティの一意の値を指定できます。 一般的なシナリオは、親要素による UI でのレンダリング方法を指定する子要素です。 たとえば、DockPanel.Dock は、DockPanel
自体ではなく、DockPanelの子要素に設定されるため、添付プロパティです。 DockPanel
クラスは、DockPropertyという名前の静的 DependencyProperty フィールドを定義し、添付プロパティのパブリック アクセサーとして GetDock メソッドと SetDock メソッドを提供します。
XAML の添付プロパティ
XAML では、構文 <attached property provider type>.<property name>
を使用して添付プロパティを設定します。添付プロパティ プロバイダーは、添付プロパティを定義するクラスです。 次の例は、DockPanel の子要素が DockPanel.Dock プロパティ値を設定する方法を示しています。
<DockPanel>
<TextBox DockPanel.Dock="Top">Enter text</TextBox>
</DockPanel>
使用法は、インスタンス名ではなく、添付プロパティ (たとえば、DockPanel) を所有し、登録する型を参照するという点で静的プロパティに似ています。
XAML 属性を使用して添付プロパティを指定する場合は、set アクションのみが適用されます。 XAML を使用してプロパティ値を直接取得することはできませんが、値を比較するための間接的なメカニズムがいくつかあります(スタイルの
WPF の添付プロパティ
添付プロパティは XAML の概念であり、依存関係プロパティは WPF の概念です。 WPF では、WPF 型のほとんどの UI 関連の添付プロパティが依存関係プロパティとして実装されます。 依存関係プロパティとして実装される WPF 添付プロパティは、メタデータの既定値を含むプロパティ メタデータなどの依存関係プロパティの概念をサポートします。
添付プロパティの使用モデル
どのオブジェクトでも添付プロパティ値を設定できますが、値を設定すると具体的な結果が生成されたり、値が別のオブジェクトによって使用されたりするわけではありません。 添付プロパティの主な目的は、さまざまなクラス階層と論理リレーションシップのオブジェクトが、添付プロパティを定義する型に共通の情報を報告する方法を提供することです。 添付プロパティの使用法は、通常、次のいずれかのモデルに従います。
- 添付プロパティを定義する型は、添付プロパティの値を設定する要素の親です。 親型は、オブジェクト ツリー構造に対して動作し、値を取得し、何らかの方法でそれらの値に対して動作する内部ロジックを介して子オブジェクトを反復処理します。
- 添付プロパティを定義する型は、さまざまな可能な親要素およびコンテンツ モデルの子要素として使用されます。
- 添付プロパティを定義する型は、サービスを表します。 その他の型は、添付プロパティの値を設定します。 次に、プロパティを設定する要素がサービスのコンテキストで評価されると、添付プロパティの値はサービス クラスの内部ロジックを通じて取得されます。
親定義の添付プロパティの例
WPF が添付プロパティを定義する一般的なシナリオは、親要素が子要素コレクションをサポートし、親要素が各子要素によって報告されたデータに基づく動作を実装する場合です。
DockPanel は、DockPanel.Dock 添付プロパティを定義します。 DockPanel
には、クラス レベルのコード (特に MeasureOverride と ArrangeOverride) があり、これはレンダリング ロジックの一部です。 DockPanel
インスタンスは、その直接の子要素のいずれかが DockPanel.Dock
の値を設定しているかどうかを確認します。 その場合、これらの値は、各子要素に適用されるレンダリング ロジックへの入力になります。 添付プロパティが直接の親を超えて要素に影響を与えることは理論的には可能ですが、入れ子になった DockPanel
インスタンスに対して定義された動作は、その直接の子要素コレクションとのみ対話することです。 したがって、DockPanel
親を持たない要素に DockPanel.Dock
を設定した場合、エラーや例外は発生せず、DockPanel
では使用されないグローバル プロパティ値を作成することになります。
コード内の添付プロパティ
WPF の添付プロパティには、CLR 名前空間の外部からプロパティが設定される可能性があるため、一般的な CLR get
および set
ラッパー メソッドはありません。 XAML プロセッサが XAML の解析時にこれらの値を設定できるようにするには、添付プロパティを定義するクラスは、Get<property name>
と Set<property name>
の形式で専用アクセサー メソッドを実装する必要があります。
次の例に示すように、専用アクセサー メソッドを使用して、コード内の添付プロパティを取得および設定することもできます。 この例では、myTextBox
は TextBox クラスのインスタンスです。
DockPanel myDockPanel = new();
TextBox myTextBox = new();
myTextBox.Text = "Enter text";
// Add child element to the DockPanel.
myDockPanel.Children.Add(myTextBox);
// Set the attached property value.
DockPanel.SetDock(myTextBox, Dock.Top);
Dim myDockPanel As DockPanel = New DockPanel()
Dim myTextBox As TextBox = New TextBox()
myTextBox.Text = "Enter text"
' Add child element to the DockPanel.
myDockPanel.Children.Add(myTextBox)
' Set the attached property value.
DockPanel.SetDock(myTextBox, Dock.Top)
myDockPanel
の子要素として myTextBox
を追加しない場合、SetDock
を呼び出しても例外が発生したり、影響を与えたりすることはありません。 DockPanel
の子要素に設定された DockPanel.Dock 値のみがレンダリングに影響し、子要素を DockPanel
に追加する前または後に値を設定した場合でも、レンダリングは同じになります。
コードの観点から見ると、添付プロパティは、プロパティ アクセサーではなくメソッド アクセサーを持つバッキング フィールドに似ています。これらのオブジェクトに対して最初に定義する必要なく、任意のオブジェクトに設定できます。
添付プロパティのメタデータ
添付プロパティのメタデータは、通常、依存関係プロパティと同じになります。 添付プロパティを登録するときは、FrameworkPropertyMetadata を使用してプロパティの特性 (プロパティがレンダリングや測定に影響するかどうかなど) を指定します。 添付プロパティのメタデータをオーバーライドして既定値を指定すると、その値は、オーバーライドするクラスのインスタンスの暗黙的な添付プロパティの既定値になります。 添付プロパティ値が設定されていない場合、メタデータを指定したクラスのインスタンスで Get<property name>
アクセサーを使用してプロパティを照会すると、既定値が報告されます。
プロパティでプロパティ値の継承を有効にするには、添付されていない依存関係プロパティの代わりに添付プロパティを使用します。 詳細については、「プロパティ値の継承
カスタム添付プロパティ
添付プロパティを作成する場合
添付プロパティを作成すると、次の場合に便利です。
定義クラス以外のクラスで使用できるプロパティ設定メカニズムが必要です。 一般的なシナリオは、UI レイアウトです。たとえば、DockPanel.Dock、Panel.ZIndex、Canvas.Top はすべて既存のレイアウト プロパティの例です。 レイアウト シナリオでは、レイアウト制御要素の子要素は、レイアウトの要件をレイアウトの親に表現し、親によって定義された添付プロパティの値を設定できます。
クラスの 1 つがサービスを表し、他のクラスでサービスをより透過的に統合する必要があります。
プロパティ ウィンドウでプロパティを編集する機能など、Visual Studio WPF デザイナーのサポートが必要です。 詳細については、「コントロールの作成の概要」を参照してください。
あなたはプロパティ値の継承を使用したいです。
添付プロパティを作成する方法
クラスが他の型でのみ使用する添付プロパティを定義している場合、クラスは DependencyObjectから派生する必要はありません。 それ以外の場合は、クラスをDependencyObject
から派生させ、WPFモデルにおける添付プロパティを依存関係プロパティとする方法に従いましょう。
DependencyProperty型の public static readonly
フィールドを宣言して、添付プロパティを定義クラスの依存関係として定義します。 次に、RegisterAttached メソッドの戻り値をフィールドに割り当てます。これは、依存関係プロパティ識別子とも呼ばれます。 識別子フィールドに <property name>Property
名前を付けることで、フィールドを表すプロパティと区別する WPF プロパティの名前付け規則に従います。 また、静的な Get<property name>
メソッドと Set<property name>
アクセサー メソッドを指定します。これにより、プロパティ システムは添付プロパティにアクセスできます。
次の例では、RegisterAttached メソッドを使用して依存関係プロパティを登録する方法と、アクセサー メソッドを定義する方法を示します。 この例では、添付プロパティの名前が HasFish
されているため、識別子フィールドの名前は HasFishProperty
で、アクセサー メソッドの名前は GetHasFish
および SetHasFish
です。
public class Aquarium : UIElement
{
// Register an attached dependency property with the specified
// property name, property type, owner type, and property metadata.
public static readonly DependencyProperty HasFishProperty =
DependencyProperty.RegisterAttached(
"HasFish",
typeof(bool),
typeof(Aquarium),
new FrameworkPropertyMetadata(defaultValue: false,
flags: FrameworkPropertyMetadataOptions.AffectsRender)
);
// Declare a get accessor method.
public static bool GetHasFish(UIElement target) =>
(bool)target.GetValue(HasFishProperty);
// Declare a set accessor method.
public static void SetHasFish(UIElement target, bool value) =>
target.SetValue(HasFishProperty, value);
}
Public Class Aquarium
Inherits UIElement
' Register an attached dependency property with the specified
' property name, property type, owner type, and property metadata.
Public Shared ReadOnly HasFishProperty As DependencyProperty =
DependencyProperty.RegisterAttached("HasFish", GetType(Boolean), GetType(Aquarium),
New FrameworkPropertyMetadata(defaultValue:=False,
flags:=FrameworkPropertyMetadataOptions.AffectsRender))
' Declare a get accessor method.
Public Shared Function GetHasFish(target As UIElement) As Boolean
Return target.GetValue(HasFishProperty)
End Function
' Declare a set accessor method.
Public Shared Sub SetHasFish(target As UIElement, value As Boolean)
target.SetValue(HasFishProperty, value)
End Sub
End Class
Get アクセサーメソッド
get
アクセサー メソッドシグネチャは、次の条件で public static object Get<property name>(DependencyObject target)
です。
target
は、添付プロパティの読み取り元となる DependencyObject です。target
型は、DependencyObject
よりも具体的にすることができます。 たとえば、DockPanel.GetDock アクセサー メソッドは、添付プロパティがUIElement
インスタンスで設定されることを意図しているため、target
を UIElement として型指定します。UiElement
は間接的にDependencyObject
から派生します。- 戻り値の型は、
object
よりも具体的にすることができます。 たとえば、戻り値はDock
列挙体である必要があるため、GetDock メソッドは戻り値を Dock として型指定します。
手記
添付プロパティの get
アクセサーは、Visual Studio や Blend for Visual Studio などのデザイン ツールでのデータ バインディングのサポートに必要です。
設定アクセサー
set
アクセサーメソッドのシグネチャは次のようにpublic static void Set<property name>(DependencyObject target, object value)
です。
target
は、添付プロパティが書き込まれる DependencyObject です。target
型は、DependencyObject
よりも具体的にすることができます。 たとえば、SetDock メソッドは、添付プロパティが UIElement インスタンスで設定されることを意図しているため、target
を UIElement として型指定します。UiElement
は間接的にDependencyObject
から派生します。value
型は、object
よりも具体的にすることができます。 たとえば、SetDock メソッドには Dock 値が必要です。 XAML ローダーは、添付プロパティ値を表すマークアップ文字列からvalue
型を生成できる必要があります。 そのため、使用する型の型変換、値シリアライザー、またはマークアップ拡張のサポートが必要です。
添付プロパティ属性
WPF では、リフレクション プロセスおよびリフレクションのコンシューマーやプロパティ情報 (デザイナーなど) に添付プロパティに関する情報を提供するいくつかの .NET 属性を定義します。 デザイナーは、WPF で定義された .NET 属性を使用してプロパティ ウィンドウに表示されるプロパティを制限し、すべての添付プロパティのグローバル リストを持つユーザーを圧倒しないようにします。 これらの属性は、独自のカスタム添付プロパティに適用することを検討してください。 .NET 属性の目的と構文については、次のリファレンス ページで説明します。
- AttachedPropertyBrowsableAttribute
- AttachedPropertyBrowsableForChildrenAttribute
- AttachedPropertyBrowsableForTypeAttribute
- AttachedPropertyBrowsableWhenAttributePresentAttribute
詳細情報
- 添付プロパティの作成の詳細については、「添付プロパティを登録する」を参照してください。
- 依存関係プロパティと添付プロパティの詳細な使用シナリオについては、「カスタム依存関係プロパティ
を参照してください。 - 添付プロパティと依存関係プロパティの両方としてプロパティを登録し、従来のプロパティ ラッパーを含めることができます。 この方法では、プロパティ ラッパーを使用して要素にプロパティを設定したり、XAML 添付プロパティ構文を使用して他の要素にプロパティを設定したりすることもできます。 例については、FrameworkElement.FlowDirectionを参照してください。
関連項目
- DependencyProperty
- 依存関係プロパティの概要
- カスタム依存関係プロパティ
- WPF での XAML
- 方法: 添付プロパティ を登録する
.NET Desktop feedback