Общие сведения о присоединенных свойствах

Присоединенное свойство — это понятие, определяемое языком XAML. Присоединенное свойство предназначено для использования в качестве типа глобального свойства, которое устанавливается для любого объекта зависимости. В Windows Presentation Foundation (WPF) присоединенные свойства обычно определяются как специализированная форма свойства зависимостей, у которых нет обычного свойства "оболочка".

Необходимые условия

В этой статье предполагается, что вы понимаете свойства зависимостей с точки зрения потребителя существующих свойств зависимостей в классах Windows Presentation Foundation (WPF) и ознакомьтесь с обзором свойств зависимостей. Чтобы следовать примерам в этой статье, вы также должны понять XAML и узнать, как писать приложения WPF.

Почему используйте присоединенные свойства

Одной из целей присоединенного свойства является разрешение разных дочерних элементов указывать уникальные значения для свойства, определенного в родительском элементе. Конкретное приложение этого сценария состоит в том, что дочерние элементы сообщают родительскому элементу о том, как они должны быть представлены в пользовательском интерфейсе.< Одним из примеров DockPanel.Dock является свойство. Свойство DockPanel.Dock создается как присоединенное свойство, так как оно предназначено для задания элементов, содержащихся в пределах, DockPanel а не для DockPanel себя. Класс DockPanel определяет статическое DependencyProperty поле с именем DockProperty, а затем предоставляет GetDock методы в SetDock качестве общедоступных методов доступа для присоединенного свойства.

Присоединенные свойства в XAML

В XAML присоединенные свойства задаются с помощью синтаксиса ПоставщикПрисоединенногоСвойства.ИмяСвойства.

Ниже приведен пример настройки DockPanel.Dock в XAML.

<DockPanel>
    <TextBox DockPanel.Dock="Top">Enter text</TextBox>
</DockPanel>

Использование несколько похоже на статическое свойство; Вы всегда ссылаетесь на тип DockPanel , который владеет и регистрирует присоединенное свойство, а не ссылается на любой экземпляр, указанный по имени.

Кроме того, поскольку присоединенное свойство в XAML является атрибутом, который устанавливается в разметке, операция задания является значимой. Нельзя напрямую получить свойство в XAML, хотя существуют некоторые косвенные механизмы для сравнения значений, такие как триггеры в стилях (подробнее см. в разделе Стилизация и использование шаблонов).

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

В Windows Presentation Foundation (WPF) большинство присоединенных к пользовательскому интерфейсу свойств типов WPF реализуются как свойства зависимостей. Присоединенные свойства — это концепция XAML, а свойства зависимостей — это концепция WPF. Так как присоединенные свойства WPF являются свойствами зависимостей, они поддерживают такие понятия свойств зависимостей, как метаданные свойств и значения по умолчанию из метаданных этого свойства.

Как присоединенные свойства используются типом владения

Хотя присоединенные свойства могут устанавливаться для любого объекта, это не означает, что задание свойства будет создавать осязаемый результат или что значение будет когда-либо использоваться другим объектом. Как правило, использование присоединенных свойств подразумевает, что объекты, поступающие из разнообразных иерархий классов или логических связей, могут передавать общую информацию в тип, который определяет присоединенное свойство. Тип, который определяет присоединенное свойство, обычно соответствует одной из следующих моделей.

  • Тип, который определяет присоединенное свойство, может являться родительским элементом для элементов, которые будут задавать значения для присоединенного свойства. Тип, который затем выполняет итерацию его дочерних объектов согласно внутренней логике относительно некоторой структуры дерева объектов, получает значения и выполняет с этими значениями какие-либо действия.

  • Тип, который определяет присоединенное свойство, будет использоваться в качестве дочернего элемента для разнообразных возможных родительских элементов и моделей содержимого.

  • Тип, который определяет присоединенное свойство, представляет службу. Другие типы устанавливают значения для присоединенного свойства. Затем, когда элемент, задающий свойство, вычисляется в контексте службы, значения присоединенного свойства получаются через внутреннюю логику класса службы.

Пример присоединенного свойства, определенного родительским элементом

Наиболее типичный сценарий, когда WPF определяет присоединенное свойство, заключается в том, что родительский элемент поддерживает коллекцию дочерних элементов, а также реализует поведение, в котором особенности поведения сообщаются отдельно для каждого дочернего элемента.

DockPanelDockPanel.Dock определяет присоединенное свойство и DockPanel имеет код уровня класса в рамках логики отрисовки (в частности, MeasureOverride иArrangeOverride). DockPanel Экземпляр всегда будет проверка, чтобы узнать, задано ли любое из его непосредственных дочерних элементов значениеDockPanel.Dock. В таком случае эти значения становятся входными данными для логики отображения, применяемой к соответствующему дочернему элементу. Вложенные DockPanel экземпляры обрабатывают собственные непосредственные дочерние коллекции элементов, но это поведение зависит от реализации того, как DockPanel обрабатываются DockPanel.Dock значения. Теоретически возможно наличие присоединенных свойств, оказывающих влияние на элементы за пределами непосредственного родителя. DockPanel.Dock Если присоединенное свойство установлено в элементе, который не DockPanel имеет родительского элемента для его действия, возникает ошибка или исключение. Это просто означает, что было задано глобальное значение свойства, но у него нет текущего DockPanel родительского элемента, который может использовать информацию.

Присоединенные свойства в коде

Присоединенные свойства в WPF не имеют типичных методов CLR "оболочки" для простого доступа к get/set. Это связано с тем, что присоединенное свойство не обязательно является частью пространства имен СРЕДЫ CLR для экземпляров, где задано свойство. Тем не менее обработчик XAML должен иметь возможность задавать эти значения при анализе XAML. Для поддержки эффективного использования присоединенного свойства тип владельца присоединенного свойства должен реализовать выделенные методы доступа в форме Get PropertyName и SetPropertyName. Такие специальные методы доступа также удобны для получения или задания присоединенного свойства в коде. С точки зрения кода присоединенное свойство аналогично резервному полю с методами доступа к методам вместо методов доступа к свойствам. Такое резервное поле может существовать для любого объекта и не требует специального определения.

В следующем примере кода показано задание присоединенного свойства в коде. В этом примере myCheckBox является экземпляром CheckBox класса.

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 бы он еще не был добавлен в качестве дочернего элемента четвертой строки кода, пятая строка кода не вызовет исключения, но значение свойства не будет взаимодействовать с DockPanel родительским элементом myDockPanel и, следовательно, не будет делать ничего. DockPanel.Dock Только значение, заданное на дочернем элементе в сочетании с присутствием родительского DockPanel элемента, приведет к эффективному поведению в отрисованном приложении. (В этом случае можно задать присоединенное свойство, а затем присоединиться к дереву. Или вы можете присоединиться к дереву, а затем задать присоединенное свойство. Любой порядок действий обеспечивает тот же результат.)

Метаданные присоединенного свойства

При регистрации свойства задано значение для указания характеристик свойства FrameworkPropertyMetadata , например, влияет ли свойство на отрисовку, измерение и т. д. Метаданные для присоединенного свойства, как правило, не отличаются от задаваемых для свойства зависимостей. Если задать значение по умолчанию в переопределении для метаданных присоединенного свойства, это значение становится значением по умолчанию неявного присоединенного свойства для экземпляров переопределяющего класса. В частности, значение по умолчанию передается, если некоторый процесс запрашивает значение присоединенного свойства с помощью метода доступа Get для этого свойства, указывая экземпляр класса, в котором заданы метаданные, и значение для этого присоединенного свойства не задано иным образом.

Если вы хотите разрешить наследование значений свойства, следует использовать присоединенные свойства, вместо неприсоединенных свойств зависимостей. Подробнее см. в разделе Наследование значения свойства.

Настраиваемые присоединенные свойства

Когда необходимо создать присоединенное свойство

Присоединенное свойство можно создать, если требуется механизм задания свойств для классов, не являющихся определяющим классом. Наиболее распространенным сценарием является макет. Примерами существующих свойств макета являются DockPanel.Dock, Panel.ZIndexи Canvas.Top. В этом сценарии элементы, которые существуют как дочерние элементы для элементов, управляющих макетом, могут индивидуально выражать требования макета для своих родительских элементов, задавая значение свойства, определяемого родительским элементом как присоединенное свойство.

Другой сценарий использования присоединенного свойства — когда класс представляет службу и требуется реализовать более прозрачную интеграцию службы классами.

Еще один сценарий — получить поддержку конструктора WPF Visual Studio, например редактирование окна свойств . Дополнительные сведения см. в разделе Общие сведения о разработке элемента управления.

Как упоминалось ранее, свойство следует регистрировать как присоединенное, если требуется использовать наследование значения свойства.

Создание присоединенного свойства

Если класс определяет присоединенное свойство строго для использования в других типах, класс не должен быть производным от DependencyObject. Но вы должны быть производными от того, следует ли DependencyObject следовать общей модели WPF, где присоединенное свойство также является свойством зависимостей.

Определите присоединенное свойство в качестве свойства зависимостей, объявив public static readonly поле типа DependencyProperty. Это поле определяется с помощью возвращаемого RegisterAttached значения метода. Имя поля должно соответствовать имени присоединенного свойства, добавленного строкой Property, чтобы следовать установленному шаблону WPF именования полей и свойств, которые они представляют. Поставщик присоединенных свойств также должен предоставлять статические методы GetPropertyName и SetPropertyName в качестве методов доступа к присоединенному свойству. Это приводит к тому, что система свойств не может использовать присоединенное свойство.

Примечание.

Если опущен метод доступа присоединенного свойства, привязка данных к свойству не будет работать в средствах разработки, таких как Visual Studio и Blend для Visual Studio.

Метод доступа get

Подпись для метода доступа GetPropertyName должна быть следующей:

public static object GetPropertyName(object target)

  • Объект target можно указать как более конкретный тип в реализации. Например, DockPanel.GetDock метод вводит параметр как , так как UIElementприсоединенное свойство предназначено только для задания экземпляров UIElement .

  • Возвращаемое значение можно указать как более конкретный тип в реализации. Например, метод типит GetDock его как Dock, так как значение может быть задано только для этого перечисления.

Метод доступа set

Подпись для метода доступа SetPropertyName должна быть следующей:

public static void SetPropertyName(object target, object value)

  • Объект target можно указать как более конкретный тип в реализации. Например, метод вводит его какUIElement, SetDock так как присоединенное свойство предназначено только для задания экземпляровUIElement.

  • Объект value можно указать как более конкретный тип в реализации. Например, метод типит SetDock его как Dock, так как значение может быть задано только для этого перечисления. Помните, что значением этого метода являются входные данные, поступающие от загрузчика XAML, когда он встречает присоединенное свойство в использовании присоединенного свойства в макете. Эти входные данные являются значением, указанным как значение атрибута XAML в разметке. Таким образом, необходимо обеспечить поддержку преобразования типов, сериализатора значений или расширений разметки для используемого типа так, чтобы соответствующий тип можно было создать из значения атрибута (которое, в конечном счете, является просто строкой).

В следующем примере показана регистрация свойств зависимостей (с помощью RegisterAttached метода), а также методы доступа GetPropertyName и SetPropertyName . В этом примере именем присоединенного свойства является IsBubbleSource. Таким образом, методы доступа должны называться GetIsBubbleSource и 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

Атрибуты присоединенного свойства

WPF определяет несколько атрибутов .NET, предназначенных для предоставления сведений о присоединенных свойствах к процессам отражения, а также для типичных пользователей информации о отражении и свойств, таких как конструкторы. Поскольку присоединенные свойства имеют тип неограниченной области, разработчикам необходим способ, который позволит избежать представления пользователям глобального списка всех присоединенных свойств, которые определены в конкретной реализации технологии, использующей XAML. Атрибуты .NET, определяемые WPF для присоединенных свойств, можно использовать для область ситуаций, когда данное присоединенное свойство должно отображаться в окне свойств. Эти атрибуты можно также применить для собственных присоединенных свойств. Назначение и синтаксис атрибутов .NET описаны на соответствующих справочных страницах:

Обучение дополнительные сведения о присоединенных свойствах

  • Дополнительные сведения о создании присоединенного свойства см. в разделе Регистрация присоединенного свойства.

  • Более сложные сценарии использования свойств зависимостей и присоединенных свойств см. в разделе Пользовательские свойства зависимостей.

  • Свойство можно также зарегистрировать как присоединенное свойство и как свойство зависимостей, но тем не менее предоставить реализации "оболочки". В этом случае свойство можно задать как для данного элемента, так и для любого элемента с помощью синтаксиса подключенных свойств XAML. Пример свойства с соответствующим сценарием для стандартных и присоединенных FrameworkElement.FlowDirectionиспользования.

См. также