添付プロパティの概要Attached Properties Overview

添付プロパティは、XAML によって定義された概念です。An attached property is a concept defined by XAML. 添付プロパティは、任意のオブジェクトに設定可能なグローバル プロパティの型として使用されることを意図しています。An attached property is intended to be used as a type of global property that is settable on any object. Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) では通常、添付プロパティは従来のプロパティ "ラッパー" を含まない依存関係プロパティの特殊な形式として定義されています。In Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF), attached properties are typically defined as a specialized form of dependency property that does not have the conventional property "wrapper".

応募Prerequisites

このトピックでは、ユーザーが Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) クラスの既存の依存関係プロパティの使用という観点から依存関係プロパティを理解し、「依存関係プロパティの概要」トピックを通読していることを前提としています。This topic assumes that you understand dependency properties from the perspective of a consumer of existing dependency properties on Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) classes, and have read the Dependency Properties Overview. このトピックの例を実行するには、XAML について理解し、WPF アプリケーションの記述方法を理解しておく必要もあります。To follow the examples in this topic, you should also understand XAML and know how to write WPF applications.

添付プロパティを使用する理由Why Use Attached Properties

添付プロパティの目的の 1 つは、親要素に実際に定義されているプロパティに対する一意の値を、異なる子要素が指定できるようにすることです。One purpose of an attached property is to allow different child elements to specify unique values for a property that is actually defined in a parent element. このシナリオの適用例として、子要素から親要素に、ユーザー インターフェイス (UI)user interface (UI) での表示方法を通知させることがあります。A specific application of this scenario is having child elements inform the parent element of how they are to be presented in the ユーザー インターフェイス (UI)user interface (UI). 1つの例として、DockPanel.Dock プロパティがあります。One example is the DockPanel.Dock property. DockPanel.Dock プロパティは、DockPanel 自体ではなく、DockPanel内に含まれる要素に設定されるように設計されているため、添付プロパティとして作成されます。The DockPanel.Dock property is created as an attached property because it is designed to be set on elements that are contained within a DockPanel, rather than on DockPanel itself. DockPanel クラスは DockPropertyという名前の静的 DependencyProperty フィールドを定義し、GetDock および SetDock メソッドを添付プロパティのパブリックアクセサーとして提供します。The DockPanel class defines the static DependencyProperty field named DockProperty, and then provides the GetDock and SetDock methods as public accessors for the attached property.

アタッチされたプロパティ (XAML の)Attached Properties in XAML

XAML では、構文 AttachedPropertyProvider.PropertyName を使用して添付プロパティを設定しますIn XAML, you set attached properties by using the syntax AttachedPropertyProvider.PropertyName

XAML で DockPanel.Dock を設定する方法の例を次に示します。The following is an example of how you can set DockPanel.Dock in XAML:

<DockPanel>
  <CheckBox DockPanel.Dock="Top">Hello</CheckBox>
</DockPanel>

使用方法は静的プロパティに似ていることに注意してください。name で指定されたインスタンスを参照するのではなく、添付プロパティを所有および登録する型 DockPanel を常に参照します。Note that the usage is somewhat similar to a static property; you always reference the type DockPanel that owns and registers the attached property, rather than referring to any instance specified by name.

さらに、XAML の添付プロパティはマークアップに設定する属性であるため、設定操作にのみ関連性があります。Also, because an attached property in XAML is an attribute that you set in markup, only the set operation has any relevance. XAML でプロパティを直接取得することはできませんが、スタイルのトリガー (詳細については、「スタイルとテンプレート」を参照) などの値を比較するための間接的な機構があります。You cannot directly get a property in XAML, although there are some indirect mechanisms for comparing values, such as triggers in styles (for details, see Styling and Templating).

WPF での添付プロパティの実装Attached Property Implementation in WPF

Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF)では、UI プレゼンテーションに関連する WPF 型に存在する添付プロパティのほとんどは、依存関係プロパティとして実装されます。In Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF), most of the attached properties that exist on WPF types that are related to UI presentation are implemented as dependency properties. 添付プロパティは XAML の概念ですが、依存関係プロパティは WPF の概念です。Attached properties are a XAML concept, whereas dependency properties are a WPF concept. WPF の添付プロパティは依存関係プロパティであるため、プロパティメタデータなどの依存関係プロパティの概念と、そのプロパティメタデータの既定値をサポートします。Because WPF attached properties are dependency properties, they support dependency property concepts such as property metadata, and default values from that property metadata.

所有する型によって添付プロパティがどのように使用されるかHow Attached Properties Are Used by the Owning Type

添付プロパティはどのオブジェクトにも設定できますが、プロパティを設定したことによって自動的に意味のある結果が得られるわけでも、値が別のオブジェクトによって使用されるわけでもありません。Although attached properties are settable on any object, that does not automatically mean that setting the property will produce a tangible result, or that the value will ever be used by another object. 一般に、添付プロパティの目的は、想定されるさまざまなクラス階層または論理関係から生じるオブジェクトが、添付プロパティを定義する型に共通する情報をレポートできるようにすることです。Generally, attached properties are intended so that objects coming from a wide variety of possible class hierarchies or logical relationships can each report common information to the type that defines the attached property. 添付プロパティを定義する型は、一般的に次のいずれかのモデルに従っています。The type that defines the attached property typically follows one of these models:

  • 添付プロパティを定義する型が、添付プロパティの値を設定する要素の親要素になるように設計されている。The type that defines the attached property is designed so that it can be the parent element of the elements that will set values for the attached property. この型の子オブジェクトは、一部のオブジェクト ツリー構造で内部ロジックを反復し、値を取得して、その値に対する処理を実行します。The type then iterates its child objects through internal logic against some object tree structure, obtains the values, and acts on those values in some manner.

  • 添付プロパティを定義する型が、想定されるさまざまな親要素およびコンテンツ モデルの子要素として使用される。The type that defines the attached property will be used as the child element for a variety of possible parent elements and content models.

  • 添付プロパティを定義する型が、サービスを表す。The type that defines the attached property represents a service. その他の型は、添付プロパティの値を設定します。Other types set values for the attached property. プロパティを設定する要素がサービスのコンテキストで評価されると、添付プロパティの値がサービス クラスの内部ロジックにより取得されます。Then, when the element that set the property is evaluated in the context of the service, the attached property values are obtained through internal logic of the service class.

親定義の添付プロパティの例An Example of a Parent-Defined Attached Property

WPF が添付プロパティを定義する最も一般的なシナリオは、親要素が子要素のコレクションをサポートし、さらに、各子要素に対して動作の詳細が個別に報告される動作を実装する場合です。The most typical scenario where WPF defines an attached property is when a parent element supports a child element collection, and also implements a behavior where the specifics of the behavior are reported individually for each child element.

DockPanelDockPanel.Dock 添付プロパティを定義し、DockPanel レンダリングロジックの一部としてクラスレベルのコードを持つことができます (具体的には、MeasureOverride および ArrangeOverride)。DockPanel defines the DockPanel.Dock attached property, and DockPanel has class-level code as part of its rendering logic (specifically, MeasureOverride and ArrangeOverride). DockPanel インスタンスは、その直接の子要素のいずれかに DockPanel.Dockの値が設定されているかどうかを常に確認します。A DockPanel instance will always check to see whether any of its immediate child elements have set a value for DockPanel.Dock. 設定されている場合は、その値が、その子要素に適用されるレンダリング ロジックの入力になります。If so, those values become input for the rendering logic applied to that particular child element. 入れ子になった DockPanel インスタンスはそれぞれ独自の直接の子要素のコレクションを処理しますが、その動作は DockPanel.Dock 値を DockPanel プロセスする方法に固有の実装です。Nested DockPanel instances each treat their own immediate child element collections, but that behavior is implementation-specific to how DockPanel processes DockPanel.Dock values. 直接の親以外の要素に影響を与える添付プロパティを所有することは、理論上は可能です。It is theoretically possible to have attached properties that influence elements beyond the immediate parent. DockPanel.Dock 添付プロパティが、DockPanel 親要素を持たない要素に設定されている場合は、エラーまたは例外は発生しません。If the DockPanel.Dock attached property is set on an element that has no DockPanel parent element to act upon it, no error or exception is raised. これは、グローバルプロパティ値が設定されていることを意味しますが、情報を使用できる現在の DockPanel 親がありません。This simply means that a global property value was set, but it has no current DockPanel parent that could consume the information.

アタッチされるプロパティ (コードの)Attached Properties in Code

WPF の添付プロパティには、get/set アクセスを簡単にするための一般的な CLR "ラッパー" メソッドはありません。Attached properties in WPF do not have the typical CLR "wrapper" methods for easy get/set access. これは、プロパティが設定されているインスタンスの場合、添付プロパティは必ずしも CLR 名前空間の一部ではないためです。This is because the attached property is not necessarily part of the CLR namespace for instances where the property is set. ただし、XAML の解析時に XAML プロセッサがその値を設定できる必要があります。However, a XAML processor must be able to set those values when XAML is parsed. 有効な添付プロパティの使用をサポートするには、添付プロパティの所有者の型がGet_PropertyName_Set_PropertyName_ の形式で専用のアクセサーメソッドを実装する必要があります。To support an effective attached property usage, the owner type of the attached property must implement dedicated accessor methods in the form Get_PropertyName_ and Set_PropertyName_. この専用のアクセサー メソッドは、コード内の添付プロパティの取得/設定でも役立ちます。These dedicated accessor methods are also useful to get or set the attached property in code. コードの観点では、添付プロパティはプロパティ アクセサーではなくメソッド アクセサーを含むバッキング フィールドに似ており、そのバッキング フィールドは特に定義することなくすべてのオブジェクトに存在することができます。From a code perspective, an attached property is similar to a backing field that has method accessors instead of property accessors, and that backing field can exist on any object rather than needing to be specifically defined.

次の例は、コードに添付プロパティを設定する方法を示しています。The following example shows how you can set an attached property in code. この例では、myCheckBoxCheckBox クラスのインスタンスです。In this example, myCheckBox is an instance of the CheckBox class.

DockPanel myDockPanel = new DockPanel();
CheckBox myCheckBox = new CheckBox();
myCheckBox.Content = "Hello";
myDockPanel.Children.Add(myCheckBox);
DockPanel.SetDock(myCheckBox, Dock.Top);
Dim myDockPanel As New DockPanel()
Dim myCheckBox As New CheckBox()
myCheckBox.Content = "Hello"
myDockPanel.Children.Add(myCheckBox)
DockPanel.SetDock(myCheckBox, Dock.Top)

XAML の場合と同様に、コードの3行目で myDockPanel の子要素として myCheckBox がまだ追加されていない場合、コードの4行目では例外は生成されませんが、プロパティ値は DockPanel 親と対話しないため、何もない。Similar to the XAML case, if myCheckBox had not already been added as a child element of myDockPanel by the third line of code, the fourth line of code would not raise an exception, but the property value would not interact with a DockPanel parent and thus would do nothing. 子要素に設定された DockPanel.Dock 値だけが DockPanel 親要素の存在と組み合わせられると、レンダリングされたアプリケーションで有効な動作が発生します。Only a DockPanel.Dock value set on a child element combined with the presence of a DockPanel parent element will cause an effective behavior in the rendered application. (この場合、添付プロパティを設定してからツリーに接続するか、(In this case, you could set the attached property, then attach to the tree. ツリーに接続してから添付プロパティを設定することができます。Or you could attach to the tree then set the attached property. どちらの操作でも、結果は同じです。)Either action order provides the same result.)

添付プロパティのメタデータAttached Property Metadata

プロパティを登録するときに、プロパティがレンダリングや測定などに影響するかどうかなど、プロパティの特性を指定するように FrameworkPropertyMetadata が設定されます。When registering the property, FrameworkPropertyMetadata is set to specify characteristics of the property, such as whether the property affects rendering, measurement, and so on. 添付プロパティのメタデータは、一般的に依存関係プロパティとの違いがありません。Metadata for an attached property is generally no different than on a dependency property. オーバーライドの既定値を添付プロパティのメタデータに指定すると、その値がオーバーライドするクラスのインスタンスの暗黙的な添付プロパティの既定値になります。If you specify a default value in an override to attached property metadata, that value becomes the default value of the implicit attached property on instances of the overriding class. 具体的には、一部のプロセスが添付プロパティの Get メソッド アクセサーを使用してそのプロパティの値のクエリを行った場合に、メタデータを指定したクラスのインスタンスが指定されており、その添付プロパティの値が設定されていないと、既定値がレポートされます。Specifically, your default value is reported if some process queries for the value of an attached property through the Get method accessor for that property, specifying an instance of the class where you specified the metadata, and the value for that attached property was otherwise not set.

プロパティでプロパティ値の継承を有効にする場合は、未接続の依存関係プロパティではなく添付プロパティを使用する必要があります。If you want to enable property value inheritance on a property, you should use attached properties rather than non-attached dependency properties. 詳細については、「プロパティ値の継承」を参照してください。For details, see Property Value Inheritance.

カスタム添付プロパティCustom Attached Properties

添付プロパティを作成する場合When to Create an Attached Property

添付プロパティは、定義クラスではないクラスで使用できるプロパティ設定機構を用意する理由がある場合に作成できます。You might create an attached property when there is a reason to have a property setting mechanism available for classes other than the defining class. この最も一般的なシナリオが、レイアウトです。The most common scenario for this is layout. 既存のレイアウトプロパティの例としては、DockPanel.DockPanel.ZIndex、および Canvas.Topがあります。Examples of existing layout properties are DockPanel.Dock, Panel.ZIndex, and Canvas.Top. これによって実現するシナリオは、レイアウト制御要素の子要素として存在する要素が、レイアウト親要素に対して個別にレイアウト要件を表現するというものです。親が添付プロパティとして定義したプロパティ値を、個々の子要素が設定します。The scenario enabled here is that elements that exist as child elements to layout-controlling elements are able to express layout requirements to their layout parent elements individually, each setting a property value that the parent defined as an attached property.

クラスがサービスを表しており、クラスでサービスをより透過的に統合できるようにしたい場合にも、添付プロパティを使用します。Another scenario for using an attached property is when your class represents a service, and you want classes to be able to integrate the service more transparently.

もう1つのシナリオは、 [プロパティ] ウィンドウの編集など、VISUAL Studio WPF デザイナーのサポートを受け取ることです。Yet another scenario is to receive Visual Studio WPF Designer support, such as Properties window editing. 詳細については、「コントロールの作成の概要」を参照してください。For more information, see Control Authoring Overview.

前述のように、プロパティ値の継承を使用する場合には、添付プロパティを登録する必要があります。As mentioned before, you should register as an attached property if you want to use property value inheritance.

添付プロパティを作成する方法How to Create an Attached Property

クラスが、他の型で使用するために厳密に添付プロパティを定義している場合、クラスは DependencyObjectから派生する必要はありません。If your class is defining the attached property strictly for use on other types, then the class does not have to derive from DependencyObject. ただし、添付プロパティが依存関係プロパティでもある WPF モデル全体に従う場合は、DependencyObject から派生する必要があります。But you do need to derive from DependencyObject if you follow the overall WPF model of having your attached property also be a dependency property.

DependencyProperty型の public static readonly フィールドを宣言することによって、添付プロパティを依存関係プロパティとして定義します。Define your attached property as a dependency property by declaring a public static readonly field of type DependencyProperty. このフィールドを定義するには、RegisterAttached メソッドの戻り値を使用します。You define this field by using the return value of the RegisterAttached method. フィールド名は、定義されている WPF パターンに従って、識別フィールドとそれが表すプロパティの名前が付けられている場合に、添付プロパティ名が文字列 Propertyと一致する必要があります。The field name must match the attached property name, appended with the string Property, to follow the established WPF pattern of naming the identifying fields versus the properties that they represent. 添付プロパティプロバイダーは、添付プロパティのアクセサーとして静的Get_PropertyName_ およびSet_PropertyName_ メソッドを提供する必要もあります。この操作を行わないと、プロパティシステムが添付プロパティを使用できなくなります。The attached property provider must also provide static Get_PropertyName_ and Set_PropertyName_ methods as accessors for the attached property; failing to do this will result in the property system being unable to use your attached property.

注意

添付プロパティの get アクセサーを省略した場合、Visual Studio や Blend for Visual Studio などのデザインツールでは、プロパティのデータバインディングは機能しません。If you omit the attached property's get accessor, data binding on the property will not work in design tools, such as Visual Studio and Blend for Visual Studio.

Get アクセサーThe Get Accessor

Get_PropertyName_ アクセサーのシグネチャは次のようにする必要があります。The signature for the Get_PropertyName_ accessor must be:

public static object GetPropertyName(object target)

  • target オブジェクトは、実装のより具体的な型として指定することができます。The target object can be specified as a more specific type in your implementation. たとえば、DockPanel.GetDock メソッドは、パラメーターを UIElementとして入力します。これは、添付プロパティが UIElement インスタンスでのみ設定されるためです。For example, the DockPanel.GetDock method types the parameter as UIElement, because the attached property is only intended to be set on UIElement instances.

  • 戻り値は、実装のより具体的な型として指定することができます。The return value can be specified as a more specific type in your implementation. たとえば、GetDock メソッドでは、値をその列挙にのみ設定できるため、Dockとして型指定されます。For example, the GetDock method types it as Dock, because the value can only be set to that enumeration.

Set アクセサーThe Set Accessor

Set_PropertyName_ アクセサーのシグネチャは次のようにする必要があります。The signature for the Set_PropertyName_ accessor must be:

public static void SetPropertyName(object target, object value)

  • target オブジェクトは、実装のより具体的な型として指定することができます。The target object can be specified as a more specific type in your implementation. たとえば、SetDock メソッドでは、添付プロパティは UIElement インスタンスでのみ設定されるため、UIElementとして型指定されます。For example, the SetDock method types it as UIElement, because the attached property is only intended to be set on UIElement instances.

  • value オブジェクトは、実装のより具体的な型として指定することができます。The value object can be specified as a more specific type in your implementation. たとえば、SetDock メソッドでは、値をその列挙にのみ設定できるため、Dockとして型指定されます。For example, the SetDock method types it as Dock, because the value can only be set to that enumeration. このメソッドの値は、マークアップの添付プロパティの使用で添付プロパティが検出されたときに XAML ローダーから生じる入力であることに注意してください。Remember that the value for this method is the input coming from the XAML loader when it encounters your attached property in an attached property usage in markup. この入力はマークアップの XAML 属性値として指定された値です。That input is the value specified as a XAML attribute value in markup. したがって、適切な型を属性値 (最終的には単なる文字列) から作成できるように、使用する型の型変換、値シリアライザー、またはマークアップ拡張サポートが必要です。Therefore there must be type conversion, value serializer, or markup extension support for the type you use, such that the appropriate type can be created from the attribute value (which is ultimately just a string).

次の例は、(RegisterAttached メソッドを使用した) 依存関係プロパティの登録と、 Get_PropertyName_ アクセサーとSet_PropertyName_ アクセサーを示しています。The following example shows the dependency property registration (using the RegisterAttached method), as well as the Get_PropertyName_ and Set_PropertyName_ accessors. この例では、添付プロパティ名は IsBubbleSource です。In the example, the attached property name is IsBubbleSource. したがって、アクセサーの名前は GetIsBubbleSource および SetIsBubbleSource である必要があります。Therefore, the accessors must be named GetIsBubbleSource and SetIsBubbleSource.

public static readonly DependencyProperty IsBubbleSourceProperty = DependencyProperty.RegisterAttached(
  "IsBubbleSource",
  typeof(Boolean),
  typeof(AquariumObject),
  new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender)
);
public static void SetIsBubbleSource(UIElement element, Boolean value)
{
  element.SetValue(IsBubbleSourceProperty, value);
}
public static Boolean GetIsBubbleSource(UIElement element)
{
  return (Boolean)element.GetValue(IsBubbleSourceProperty);
}
Public Shared ReadOnly IsBubbleSourceProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsBubbleSource", GetType(Boolean), GetType(AquariumObject), New FrameworkPropertyMetadata(False, FrameworkPropertyMetadataOptions.AffectsRender))
Public Shared Sub SetIsBubbleSource(ByVal element As UIElement, ByVal value As Boolean)
    element.SetValue(IsBubbleSourceProperty, value)
End Sub
Public Shared Function GetIsBubbleSource(ByVal element As UIElement) As Boolean
    Return CType(element.GetValue(IsBubbleSourceProperty), Boolean)
End Function

添付プロパティの属性Attached Property Attributes

WPF では、添付プロパティに関する情報をリフレクションプロセスに提供するためのいくつかの .NET 属性、およびリフレクションとプロパティ情報 (デザイナーなど) の一般的なユーザーを定義します。WPF defines several .NET attributes that are intended to provide information about attached properties to reflection processes, and to typical users of reflection and property information such as designers. 添付プロパティに含まれる型は膨大な範囲に及ぶため、デザイナーには XAML を使用する特定のテクノロジの実装に定義されたすべての添付プロパティのグローバル リストがユーザーに表示されないようにするための手段が必要となります。Because attached properties have a type of unlimited scope, designers need a way to avoid overwhelming users with a global list of all the attached properties that are defined in a particular technology implementation that uses XAML. WPF が添付プロパティ用に定義する .NET 属性を使用して、特定の添付プロパティを [プロパティ] ウィンドウに表示する必要がある状況のスコープを設定できます。The .NET attributes that WPF defines for attached properties can be used to scope the situations where a given attached property should be shown in a properties window. また、この属性をカスタム添付プロパティに適用するという選択肢もあります。You might consider applying these attributes for your own custom attached properties also. .NET 属性の目的と構文については、適切なリファレンスページで説明されています。The purpose and syntax of the .NET attributes is described on the appropriate reference pages:

添付プロパティの詳細を学習するLearning More About Attached Properties

  • 添付プロパティの作成の詳細については、「方法: 添付プロパティを登録する」を参照してください。For more information on creating an attached property, see Register an Attached Property.

  • 依存関係プロパティおよび添付プロパティの高度な使用シナリオについては、「カスタム依存関係プロパティ」を参照してください。For more advanced usage scenarios for dependency properties and attached properties, see Custom Dependency Properties.

  • プロパティは添付プロパティとしても依存関係プロパティとしても登録できますが、"ラッパー" 実装は公開したままにすることができます。You can also register a property as an attached property, and as a dependency property, but then still expose "wrapper" implementations. この場合、プロパティをその要素に設定することも、XAML の添付プロパティの構文を使用して任意の要素に設定することもできます。In this case, the property can be set either on that element, or on any element through the XAML attached property syntax. 標準とアタッチの両方の使用に適したシナリオを持つプロパティの例としては、FrameworkElement.FlowDirectionがあります。An example of a property with an appropriate scenario for both standard and attached usages is FrameworkElement.FlowDirection.

関連項目See also