Общие сведения о вложенных свойствах зависимостей
Присоединенное свойство — это понятие, определяемое языком XAML. Присоединенное свойство предназначено для использования в качестве типа глобального свойства, которое может быть задано для любого объекта. В Windows Presentation Foundation (WPF) присоединенные свойства обычно определяются как особая форма свойства зависимости, не имеющего обычной "оболочки" свойства.
Предварительные требования
Предполагается, что вы имеете представление о свойствах зависимостей с точки зрения потребителя существующих свойств зависимостей в классах Windows Presentation Foundation (WPF) и ознакомились с разделом Общие сведения о свойствах зависимостей. Чтобы выполнить примеры в этом разделе, следует также понимать XAML и знаете, как создавать приложения WPF.
Зачем использовать вложенные свойства
Среди прочего, присоединенные свойства позволяют разным дочерним элементам задавать уникальные значения для свойства, которое фактически определено в родительском элементе. Конкретным примером этого сценария является уведомление дочерними элементами родительского элемента о порядке их представления в UI . Одним из примеров является DockPanel.Dock свойство. DockPanel.Dock Свойство создается как присоединенное свойство, так как он предназначен для элементов, содержащихся в DockPanel, а не для DockPanel сам. DockPanel Класс определяет статическое DependencyProperty поле с именем DockProperty, а затем предоставляет GetDock и SetDock методы как открытые методы доступа для вложенных свойств.
Присоединенные свойства в XAML
В XAML присоединенные свойства задаются с помощью синтаксиса ПоставщикПрисоединенногоСвойства.ИмяСвойства.
Ниже приведен пример как можно задать DockPanel.Dock в XAML:
<DockPanel>
<CheckBox DockPanel.Dock="Top">Hello</CheckBox>
</DockPanel>
Обратите внимание, что использование похож на статическое свойство; Вы всегда ссылаться на тип DockPanel , является владельцем и регистрирует присоединенное свойство, а не ссылается на экземпляр, заданный по имени.
Кроме того, поскольку присоединенное свойство в XAML является атрибутом, который устанавливается в разметке, операция задания является значимой. Нельзя напрямую получить свойство в XAML, хотя существуют некоторые косвенные механизмы для сравнения значений, такие как триггеры в стилях (подробнее см. в разделе Стилизация и использование шаблонов).
Реализация присоединенного свойства в WPF
В Windows Presentation Foundation (WPF), большинство присоединенных свойств, которые существуют для типов WPF, которые связаны с представлением пользовательского интерфейса реализуются как свойства зависимости. Присоединенные свойства являются понятием XAML, тогда как свойства зависимости являются понятием WPF. Поскольку WPF присоединенные свойства являются свойствами зависимостей, они поддерживают понятия свойств зависимости, такие как метаданные свойства и значения по умолчанию из этих метаданных свойства.
Как присоединенные свойства используются типом владельца
Хотя присоединенные свойства могут устанавливаться для любого объекта, это не означает, что задание свойства будет создавать осязаемый результат или что значение будет когда-либо использоваться другим объектом. Как правило, использование присоединенных свойств подразумевает, что объекты, поступающие из разнообразных иерархий классов или логических связей, могут передавать общую информацию в тип, который определяет присоединенное свойство. Тип, который определяет присоединенное свойство, обычно соответствует одной из следующих моделей.
Тип, который определяет присоединенное свойство, может являться родительским элементом для элементов, которые будут задавать значения для присоединенного свойства. Тип, который затем выполняет итерацию его дочерних объектов согласно внутренней логике относительно некоторой структуры дерева объектов, получает значения и выполняет с этими значениями какие-либо действия.
Тип, который определяет присоединенное свойство, будет использоваться в качестве дочернего элемента для разнообразных возможных родительских элементов и моделей содержимого.
Тип, который определяет присоединенное свойство, представляет службу. Другие типы устанавливают значения для присоединенного свойства. Затем, когда элемент, задающий свойство, вычисляется в контексте службы, значения присоединенного свойства получаются через внутреннюю логику класса службы.
Пример присоединенного свойства, определенного родительским элементом
Наиболее типичный сценарий, где WPF определяет присоединенное свойство — когда родительский элемент поддерживает коллекцию дочерних элементов, а также реализует поведение, на котором особенности поведения передаются отдельно для каждого дочернего элемента.
DockPanel Определяет DockPanel.Dock вложенное свойство зависимостей, и DockPanel содержит код уровня класса как часть логики отображения (в частности, MeasureOverride и ArrangeOverride). Объект DockPanel экземпляр всегда проверяет ли любой из его непосредственные дочерние элементы задали значение DockPanel.Dock. В таком случае эти значения становятся входными данными для логики отображения, применяемой к соответствующему дочернему элементу. Вложенные DockPanel экземпляров каждого обрабатывать свои собственные коллекции непосредственных дочерних элементов, но это поведение зависит от реализации как DockPanel процессы DockPanel.Dock значения. Теоретически возможно наличие присоединенных свойств, оказывающих влияние на элементы за пределами непосредственного родителя. Если DockPanel.Dock присоединенное свойство имеет значение для элемента, который не имеет DockPanel возникает родительского элемента, с которым выполняется действие его, ошибка или исключение. Это просто означает, что значение глобального свойства было задано, но оно не имеет текущего DockPanel родителя, который может использовать эти данные.
Присоединенные свойства в коде
Присоединенные свойства в WPF не имеют обычных CLR методов «оболочки» для простого получения и задания доступа. Это происходит потому, что присоединенное свойство не обязательно входит в пространство имен CLR для экземпляров, в которых задано это свойство. Тем не менее обработчик XAML должен иметь возможность задавать эти значения при анализе XAML. Для поддержки эффективного использования присоединенных свойств, тип владельца присоединенного свойства должен реализовывать специальные методы доступа в форме Get_PropertyName_ и Set_PropertyName_. Такие специальные методы доступа также удобны для получения или задания присоединенного свойства в коде. С точки зрения кода присоединенное свойство аналогично резервному полю с методами доступа к методам вместо методов доступа к свойствам. Такое резервное поле может существовать для любого объекта и не требует специального определения.
В следующем примере кода показано задание присоединенного свойства в коде. В этом примере 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. В этом сценарии элементы, которые существуют как дочерние элементы для элементов, управляющих макетом, могут индивидуально выражать требования макета для своих родительских элементов, задавая значение свойства, определяемого родительским элементом как присоединенное свойство.
Другой сценарий использования присоединенного свойства — когда класс представляет службу и требуется реализовать более прозрачную интеграцию службы классами.
Еще одним сценарием является для получения поддержки конструктора WPF для Visual Studio, такие как свойства редактирование окна. Дополнительные сведения см. в разделе Общие сведения о разработке элементов управления.
Как упоминалось ранее, свойство следует регистрировать как присоединенное, если требуется использовать наследование значения свойства.
Создание присоединенного свойства
Если ваш класс определяет присоединенное свойство исключительно для использования на других типов, то не обязательно должен быть производным от DependencyObject. Но вам нужно наследовать DependencyObject Если вы следуете общей моделью WPF что присоединенное свойство также быть свойством зависимостей.
Определите присоединенное свойство как свойство зависимостей, объявив public static readonly
поле типа DependencyProperty. Это поле определяется с помощью возвращаемого значения RegisterAttached метод. Имя поля должно совпадать с именем присоединенного свойства, с добавлением строки Property
, чтобы соответствовать установленным WPF шаблону именования идентифицирующие поля и свойств, которые они представляют. Поставщик присоединенного свойства также должен предоставлять статические Get_PropertyName_ и Set_PropertyName_ методов как методы доступа для вложенных свойств зависимостей; Если сделать это приведет к в свойстве система не сможет использовать присоединенное свойство.
Note
Если опустить метод доступа get присоединенного свойства, привязка данных для этого свойства не будет работать в средствах разработки, таких как Visual Studio и Expression Blend.
Метод доступа get
Сигнатура для Get_PropertyName_ должен быть метод доступа:
public static object GetPropertyName(object target)
Объект
target
можно указать как более конкретный тип в реализации. Например DockPanel.GetDock метод типизирует параметр как UIElement, так как присоединенное свойство предназначено только для настройки UIElement экземпляров.Возвращаемое значение можно указать как более конкретный тип в реализации. Например GetDock метод типизирует его как Dock, так как значение можно задать только это перечисление.
Метод доступа set
Сигнатура для Set_PropertyName_ должен быть метод доступа:
public static void SetPropertyName(object target, object value)
Объект
target
можно указать как более конкретный тип в реализации. Например SetDock метод типизирует его как UIElement, так как присоединенное свойство предназначено только для настройки UIElement экземпляров.Объект
value
можно указать как более конкретный тип в реализации. Например SetDock метод типизирует его как Dock, так как значение можно задать только это перечисление. Помните, что значением этого метода являются входные данные, поступающие от загрузчика XAML, когда он встречает присоединенное свойство в использовании присоединенного свойства в макете. Эти входные данные являются значением, указанным как значение атрибута XAML в разметке. Таким образом, необходимо обеспечить поддержку преобразования типов, сериализатора значений или расширений разметки для используемого типа так, чтобы соответствующий тип можно было создать из значения атрибута (которое, в конечном счете, является просто строкой).
В следующем примере показано регистрации свойства зависимостей (с помощью RegisterAttached метод), а также Get_PropertyName_ и Set_PropertyName_ методы доступа. В этом примере именем присоединенного свойства является 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.