Синтаксис 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...]" ... />

or

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Примечание.

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

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 должно существовать в качестве свойства зависимости от типа, являющегося типом propertyName PropertyType.

Косвенное назначение анимации необходимо из-за примененных стилей и шаблонов. Чтобы настроить целевой объект анимации, необходимо наличие 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[]) для сложной анимации. Последний конструктор использует строку токена для первого параметра и массив объектов, которые заполняют позиции в строке токена, чтобы определить отношение пути к свойству.

См. также