Поделиться через


Синтаксис PropertyPath в XAML

Объект PropertyPath поддерживает сложный встроенный синтаксис XAML для настройки различных свойств, которые принимают тип PropertyPath как свое значение. В этом разделе описывается синтаксис PropertyPath применительно к синтаксису привязки и анимации.

Где используется PropertyPath

PropertyPath представляет собой общий объект, который используется в нескольких функциях Windows Presentation Foundation (WPF). Несмотря на использование общего PropertyPath для передачи информации о пути к свойству, варианты использования для каждой функциональной области, в которой PropertyPath используется как тип, различаются. Таким образом, более практично документировать синтаксис для каждой функции.

В основном WPF использует PropertyPath для описания путей объектной модели для нахождения свойств источника данных объекта и для описания конечного пути для целевой анимации.

Некоторые свойства стиля и шаблона, такие как Setter.Property, принимают полное имя свойства, которое внешне напоминает PropertyPath. Но это не является истинным PropertyPath; вместо этого это специализированное использование формата строки owner.property, которое включено обработчиком XAML WPF в сочетании с преобразователем типов для DependencyProperty.

PropertyPath для объектов в привязке данных

Привязка данных является функцией WPF, которую можно привязать к целевому значению любого свойства зависимостей. Однако источник такой привязки данных не обязательно должен быть свойством зависимостей. Это может быть любой тип свойства, распознаваемый применимым поставщиком данных. Пути свойств особенно используются для ObjectDataProvider, который применяется для получения источников привязки из объектов CLR и их свойств.

Обратите внимание, что привязка данных к XML не использует PropertyPath, поскольку не использует Path в Binding. Вместо него используйте XPath и укажите допустимый синтаксис XPath в модели DOM данных. XPath также указывается как строка, но не документируется здесь. См. раздел Привязка к XML-данным с помощью XMLDataProvider и запросов XPath.

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

Единственное свойство непосредственного объекта в качестве контекста данных

<Binding Path="propertyName" ... />

propertyName должно определяться как имя свойства, которое присутствует в текущем DataContext для использования Path. Если привязка обновляет источник, это свойство должно быть доступно для чтения и записи, а исходный объект должен быть изменяемым.

Одиночный индексатор на непосредственном объекте в качестве контекста данных

<Binding Path="[key]" ... />

key должен быть либо типизированным индексом для словаря или хэш-таблицы, либо целочисленным индексом массива. Кроме того, значение ключа должно быть типом, который можно непосредственно привязать к свойству, в котором оно применяется. Например, хэш-таблица, содержащая строковые ключи и строковые значения, может использоваться таким образом для привязки к тексту для TextBox. Либо, если ключ указывает на коллекцию или субиндекс, этот синтаксис можно использовать для привязки к целевому свойству коллекции. В противном случае необходимо ссылаться на конкретное свойство, например с помощью синтаксиса <Binding Path="[key].propertyName" .../>.

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

Несколько свойств (нацеливание на косвенные свойства)

<Binding Path="propertyName.propertyName2" ... />

propertyName должно разрешаться как имя свойства, которое является текущим DataContext. Свойствами пути propertyName и propertyName2 могут быть любые свойства, которые существуют в связи, где propertyName2 — свойство, которое существует в типе, являющемся значением propertyName.

Единичное свойство, присоединенное или иначе квалифицированное по типу.

<object property="(ownerType.propertyName)" ... />

Скобки указывают на то, что это свойство в PropertyPath должно быть создано с использованием частичной квалификации. Может использоваться пространство имен XML для поиска типа с соответствующим сопоставлением. ownerType выполняет поиск типов, к которым у обработчика XAML есть доступ, посредством деклараций XmlnsDefinitionAttribute в каждой сборке. В большинстве приложений есть пространство имен XML по умолчанию, сопоставленное пространству имен http://schemas.microsoft.com/winfx/2006/xaml/presentation, поэтому префикс обычно требуется только для настраиваемых типов или типов вне этого пространства имен. propertyName должно разрешаться как имя свойства, существующего в ownerType. Этот синтаксис обычно используется в одном из следующих случаев.

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

  • Свойство является присоединенным свойством.

  • Выполняется привязка к статическому свойству.

Для использования в качестве цели раскадровки свойство, указанное как propertyName, должно быть DependencyProperty.

Обход источников данных (привязка к иерархиям коллекций)

<object Path="propertyName/propertyNameX" ... />

/ в этом синтаксисе используется для навигации в иерархическом объекте источника данных. Поддерживается несколько шагов в иерархии с последовательными символами /. Обход источников учитывает текущую позицию указателя записи, которая определяется синхронизацией данных с пользовательским интерфейсом его представления. Дополнительные сведения о привязке к иерархическим объектам источника данных и концепции указателя текущей записи в привязке данных см. в разделе Использование шаблона "Основной/подробности" с иерархическими данными или Общие сведения о привязке данных.

Замечание

Внешне этот синтаксис походит на XPath. Истинное выражение XPath для привязки к источнику данных XML не используется как значение Path. Вместо этого его следует использовать для взаимоисключающего свойства XPath.

Представления коллекции

Для обращения к именованному представлению коллекции необходимо указать символ решетки перед названием представления (#).

Указатель текущей записи

Чтобы ссылаться на указатель текущей записи для представления коллекции или сценария привязки данных "Основной/подробности", в начале строки пути поставьте косую черту (/). Проход по любому пути, начинающемуся с косой черты, осуществляется с текущей позиции указателя записи.

Несколько индексаторов

<object Path="[index1,index2...]" ... />

или

<object Path="propertyName[index,index2...]" ... />

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

По умолчанию значения индексатора вводятся с использованием характеристик базового объекта. При необходимости можно указать тип индекса. Дополнительные сведения о вводе индексаторов см. в разделе Binding.Path.

Смешанный синтаксис

Можно сочетать каждый из синтаксисов, показанных выше. Ниже приведен пример, в котором создается путь к свойству для цвета в определенных координатах x, y свойства ColorGrid, содержащего массив сетки пикселей объектов SolidColorBrush:

<Rectangle Fill="{Binding ColorGrid[20,30].SolidColorBrushResult}" ... />

Escape-символы для строк путей к свойствам

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

  • Внутри индексаторов ([ ]), символ курсора (^) экранирует следующий символ.

  • Необходимо заменить символы на их XML-сущности, если эти символы имеют специальное значение в XML. Используйте & для экранирования символа "&". Используйте > для экранирования конечного тега>.

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

    • Обратная косая черта (\) сама по себе является escape-символом.

    • Знак равенства (=) разделяет имя и значение свойства.

    • Запятая (,) разделяет свойства.

    • Завершающая фигурная скобка (}) — это конец расширения разметки.

Замечание

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

PropertyPath для целевых объектов анимации

Целевое свойство анимации должно быть свойством зависимости, которое принимает либо Freezable, либо примитивный тип. Однако целевое свойство типа и конечное анимированное свойство могут существовать в различных объектах. Для анимаций путь к свойству используется для определения связи между свойством целевого объекта именованной анимации и заданным целевым свойством анимации путем обхода отношений "объект/свойство" в значениях свойств.

Общие рекомендации по объектам и свойствам для анимаций

Подробнее о концепциях анимации в целом см. в разделах Общие сведения о раскадровке и Общие сведения об анимации .

Тип значения или анимируемое свойство должны либо иметь тип Freezable, либо быть примитивом. Свойство, которое начинает путь, должно представлять имя свойства зависимости, которое существует в указанном типе TargetName.

Для поддержки клонирования в целях анимации объекта Freezable, который уже был заморожен, объект, указываемый с помощью TargetName, должен быть производным классом FrameworkElement или FrameworkContentElement.

Одно свойство в целевом объекте

<animation Storyboard.TargetProperty="propertyName" ... />

propertyName должно разрешаться в название свойства зависимости, которое существует в указанном типе TargetName.

Косвенное ориентирование свойства

<animation Storyboard.TargetProperty="propertyName.propertyName2" ... />

propertyName должно быть свойством, которое является либо типом значения Freezable, либо примитивом, который существует в указанном типе TargetName.

propertyName2 должно быть именем свойства зависимостей, существующего в объекте, который является значением propertyName. Другими словами, propertyName2 должно существовать в качестве свойства зависимости от типа, являющегося типом propertyNamePropertyType.

Косвенное назначение анимации необходимо из-за примененных стилей и шаблонов. Чтобы настроить целевой объект анимации, необходимо наличие TargetName в целевом объекте. Это имя устанавливается с помощью x:Name или Name. Хотя элементы шаблона и стиля также могут иметь имена, эти имена действительны только в области имен стиля и шаблона. (Если шаблоны и стили совместно использовали области имен с разметкой приложения, имена не могут быть уникальными. Стили и шаблоны буквально используются совместно между экземплярами, что привело бы к использованию повторяющихся имен.) Таким образом, если отдельные свойства элемента, которые вы хотите анимировать, происходят из стиля или шаблона, необходимо начать с именованного экземпляра элемента, который не из шаблона стиля, а затем обратиться к визуальному дереву стиля или шаблона, чтобы добраться до свойства, которое вы хотите анимировать.

Например, свойство Background для Panel является полным Brush (фактически SolidColorBrush), который поступил из шаблона темы. Чтобы полностью анимировать Brush, потребовалась бы BrushAnimation (возможно, одна для каждого типа Brush), а такого типа не существует. Чтобы анимировать кисть, вместо этого анимируются свойства определенного типа Brush. Необходимо переместиться из SolidColorBrush в Color, чтобы применить ColorAnimation там. Путь к свойству в этом примере будет Background.Color.

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

<animation Storyboard.TargetProperty="(ownerType.propertyName)" ... />

Скобки указывают на то, что это свойство в PropertyPath должно быть создано с использованием частичной квалификации. Для поиска типа может использоваться пространство имен XML. ownerType выполняет поиск типов, к которым у обработчика XAML есть доступ, через объявления XmlnsDefinitionAttribute в каждой сборке. В большинстве приложений есть пространство имен XML по умолчанию, сопоставленное пространству имен http://schemas.microsoft.com/winfx/2006/xaml/presentation, поэтому префикс обычно требуется только для настраиваемых типов или типов вне этого пространства имен. propertyName должно соответствовать имени свойства, существующего в ownerType. Свойство, указанное как propertyName должно быть DependencyProperty. (Все присоединенные свойства WPF реализуются как свойства зависимостей, поэтому эта проблема связана только с пользовательскими присоединенными свойствами.)

Индексаторы

<animation Storyboard.TargetProperty="propertyName.propertyName2[index].propertyName3" ... />

Большинство свойств зависимостей или типов Freezable не поддерживают индексатор. Таким образом, единственное использование индексатора в пути к анимации — это промежуточное положение между свойством, которое запускает цепочку в именованном целевом объекте и конечным анимированным свойством. В предоставленном синтаксисе это propertyName2. Например, может потребоваться использовать индексатор, если промежуточные свойство является коллекцией, например TransformGroup, на пути к свойству, например RenderTransform.Children[1].Angle.

PropertyPath в коде

Использование кода для PropertyPath, включая создание PropertyPath, документировано в справочном разделе для PropertyPath.

Обычно, PropertyPath предназначен для использования двух различных конструкторов, один для привязки и простейших анимаций и один для сложных анимаций. Используйте сигнатуру PropertyPath(Object) для привязок, в которых объект является строкой. Используйте сигнатуру PropertyPath(Object) для одношаговых путей к анимации, где объектом является DependencyProperty. Используйте сигнатуру PropertyPath(String, Object[]) для сложной анимации. Последний конструктор использует строку токена для первого параметра и массив объектов, которые заполняют позиции в строке токена, чтобы определить отношение пути к свойству.

См. также