Общие сведения о вложенных свойствах зависимостей

Обновлен: Ноябрь 2007

Вложенное свойство является понятием Язык XAML (Extensible Application Markup Language). Вложенное свойство предназначено для использования в качестве типа глобального свойства, которое может быть задано для любого объекта. В Windows Presentation Foundation (WPF) вложенные свойства обычно определяются как особая форма свойства зависимости, не имеющая «оболочки» традиционного свойства.

В этом разделе содержатся следующие подразделы.

  • Необходимые компоненты
  • Зачем использовать вложенные свойства?
  • Вложенные свойства в XAML
  • Как вложенные свойства зависимостей используются типом-владельцем
  • Вложенные свойства в коде
  • Метаданные вложенного свойства
  • Пользовательские вложенные свойства
  • Дополнительные сведения о вложенных свойствах зависимостей
  • Связанные разделы

Необходимые компоненты

Этот раздел предполагает понимание свойств зависимости с точки зрения пользователя существующих свойств зависимости для классов Windows Presentation Foundation (WPF) и предварительное прочтение раздела Общие сведения о свойствах зависимости. Для понимания примеров в этом разделе также требуется понимать Язык XAML (Extensible Application Markup Language) и знать порядок написания приложений WPF.

Зачем использовать вложенные свойства?

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

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

В XAML вложенные свойства задаются с использованием синтаксиса AttachedPropertyProvider.PropertyName

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Вложенные свойства в коде

Вложенные свойства в WPF не имеют обычной CLR «оболочки» методов доступа Get/Set. Это обусловлено тем, что вложенное свойство не обязательно является частью пространства имен CLR для экземпляров, в которых оно задано. Однако считыватель XAML должен иметь возможность задавать эти значения при обработке XAML. Для эффективности вложенного свойства зависимостей тип-владелец вложенного свойства зависимостей должен реализовывать выделенные методы доступа в форме GetPropertyName и SetPropertyName. Эти выделенные методы доступа определяют порядок получения или установки данного вложенного свойства в коде. С точки зрения кода вложенное свойство идентично резервному полю, имеющему метод доступа вместо метода доступа к свойству, и это резервное поле может существовать для любого объекта, не требуя специального определения.

Следующий пример показывает, как можно задать вложенное свойство в коде. В этом примере myCheckBox представляет собой экземпляр класса CheckBox.

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

Аналогично случаю с XAML, если myCheckBox не добавлен как дочерний элемент myDockPanel третьей строкой кода, то четвертая строка кода не приведет к исключению, но значение свойства не будет взаимодействовать с родительским элементом DockPanel и, следовательно, не будет ни на что влиять. Только значение DockPanel.Dock, заданное для дочернего элемента, в сочетании с наличием родительского элемента DockPanel, будет влиять на поведение в отображаемом приложении.

Метаданные вложенного свойства

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

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

Пользовательские вложенные свойства

Когда следует создавать вложенное свойство

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

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

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

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

Как создать вложенное свойство

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

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

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

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

public static object GetPropertyName(object target)

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

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

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

Сигнатура для метода доступа SetИмяСвойства должна быть следующей:

public static void SetИмяСвойства(object target, object value)

  • Объект target может быть задан в реализации как более конкретный тип. Например, метод SetDock определяет тип параметра как UIElement, поскольку только вложенное свойство предназначено для установки только на экземплярах 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);
}

Атрибуты вложенного свойства

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

Дополнительные сведения о вложенных свойствах зависимостей

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

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

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

См. также

Задачи

Практическое руководство. Регистрация вложенного свойства зависимостей

Основные понятия

Общие сведения о свойствах зависимости

Пользовательские свойства зависимостей

Общие сведения о XAML

Ссылки

DependencyProperty