Общие сведения о вложенных свойствах зависимостей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

Среди прочего, присоединенные свойства позволяют разным дочерним элементам задавать уникальные значения для свойства, которое фактически определено в родительском элементе.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. Конкретным примером этого сценария является уведомление дочерними элементами родительского элемента о порядке их представления в пользовательский интерфейс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 пользовательский интерфейсuser interface (UI). Одним из примеров является DockPanel.Dock свойство.One example is the DockPanel.Dock property. Свойство создается как присоединенное свойство, так как оно предназначено для установки в элементах, содержащихся DockPanelв, а не на DockPanel самом себе. DockPanel.DockThe 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. DependencyProperty DockProperty GetDock Класс определяет статическое поле с именем, а затем предоставляет методы и SetDock в качестве открытых методов доступа для присоединенного свойства. DockPanelThe DockPanel class defines the static DependencyProperty field named DockProperty, and then provides the GetDock and SetDock methods as public accessors for the attached property.

Вложенные свойства в XAMLAttached Properties in XAML

В XAML присоединенные свойства задаются с помощью синтаксиса ПоставщикПрисоединенногоСвойства.ИмяСвойства.In XAML, you set attached properties by using the syntax AttachedPropertyProvider.PropertyName

Ниже приведен пример того, как можно задать DockPanel.Dock в XAML:The following is an example of how you can set DockPanel.Dock in XAML:

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

Обратите внимание, что использование в некоторой степени похоже на статическое свойство. всегда следует ссылаться на тип 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).

Реализация присоединенного свойства в WPFAttached Property Implementation in WPF

В Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF)большинство присоединенных свойств, которые существуют в типах 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.

DockPanelОпределяет присоединенное свойство и DockPanel содержит код уровня класса как часть его логики отрисовки (в частности, MeasureOverride и ArrangeOverride). DockPanel.DockDockPanel defines the DockPanel.Dock attached property, and DockPanel has class-level code as part of its rendering logic (specifically, MeasureOverride and ArrangeOverride). Экземпляр всегда проверяет, установил ли какой-либо из его непосредственных дочерних элементов значение для DockPanel.Dock. DockPanelA 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 , DockPanel.Dock как обрабатываются значения.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 имеет родительского элемента, который будет работать с ним, то ошибка или исключение не возникает. DockPanel.DockIf 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 не имеют типовых методов оболочки CLR для простого доступа get/set.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. В этом примере myCheckBox — это экземпляр CheckBox класса.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 myCheckBox , если он еще не был добавлен в качестве дочернего myDockPanel элемента третьей строкой кода, то в четвертой строке кода не будет вызываться исключение, но значение свойства не 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 родительского элемента, приведет к эффективному поведению в приложении, готовом для просмотра. DockPanel.DockOnly 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.Dock, Panel.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.

Еще один сценарий — получение поддержки конструктора WPF Visual Studio, например изменение окна свойств .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. Но вам нужно создать производную от DependencyObject , если вы подберете общую модель WPF, в которой присоединенное свойство также является свойством зависимостей.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.

Определите присоединенное свойство как свойство зависимостей, объявляя public static readonly поле типа. DependencyPropertyDefine 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. Имя поля должно совпадать с именем присоединенного свойства, добавленного со строкой Property, чтобы соответствовать установленному шаблону WPF именования идентифицирующих полей относительно свойств, которые они представляют.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 и Expression Blend.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 Expression Blend.

Метод доступа getThe 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.

Метод доступа setThe 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 Framework.NET Framework attributes , которые предназначены для предоставления сведений о вложенных свойствах процессам отражения, а также обычным пользователям отражения и информации о свойствах, таких как конструкторы.WPF defines several Атрибуты .NET Framework.NET Framework 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. Объект Атрибуты .NET Framework.NET Framework attributes , определяемый в WPF для присоединенных свойств, может использоваться для определения области ситуаций, в которых заданное присоединенное свойство должно отображаться в окне свойств.The Атрибуты .NET Framework.NET Framework 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 Framework.NET Framework attributes описаны в соответствующих разделах справочника.The purpose and syntax of the Атрибуты .NET Framework.NET Framework 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