Расширения разметки и XAML

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

В этом разделе рассматривается понятие расширений разметки для Язык XAML (Extensible Application Markup Language), включая их синтаксические правила, назначение и класс формирующей их объектной модели.

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

  • Обработчики XAML и расширения разметки
  • Базовый синтаксис расширения разметки
  • Расширения разметки, характерные для WPF
  • Расширения разметки, определенные XAML
  • Дополнительные сведения о синтаксисе расширения разметки
  • Связанные разделы

Обработчики XAML и расширения разметки

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

Базовый синтаксис расширения разметки

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

При использовании расширения для предоставления значения атрибута, синтаксисом, указывающим обработчику XAML расширение разметки, является наличие открывающей и закрывающей фигурных скобок ("{" и "}"). Затем тип расширения разметки определяется лексемой строки, следующей сразу за открывающейся фигурной скобкой.

При использовании в синтаксисе элемента свойства расширение разметки, как правило, визуально не отличается от любого другого элемента, используемого для предоставления нужного значения элемента свойства: объявление элемента XAML, который ссылается на класс расширения разметки как на элемент, заключается в угловые скобки (<>).

Расширения разметки, характерные для WPF

Наиболее распространенными расширениями разметки, используемыми при программировании WPF, являются расширения, которые поддерживают ссылки на ресурсы (StaticResource и DynamicResource) и расширения, поддерживающие привязку данных (Binding).

StaticResource предоставляет значение для свойства XAML, замещая значение уже определенного ресурса. Подробные сведения см. в разделе Расширение разметки StaticResource.

DynamicResource предоставляет значение для свойства XAML в виде ссылки на ресурс, отложенной до времени выполнения. Ссылка на динамический ресурс вызывает новый поиск каждый раз, когда осуществляется доступ к такому ресурсу. Подробные сведения см. в разделе Расширение разметки DynamicResource.

Binding предоставляет привязанное к данным значение свойства в контексте данных, который применяется к элементу. Это расширение разметки относительно сложное, так как оно включает важный встроенный синтаксис для определения привязки данных. Подробные сведения см. в разделе Привязка расширения разметки.

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

TemplateBinding позволяет шаблону элемента управления использовать значения шаблонных свойств, получаемых из определенных объектной моделью свойств класса, который будет использовать шаблон. Подробные сведения см. в разделе Расширение разметки TemplateBinding. Дополнительные сведения о практическом использовании TemplateBinding см. в разделе Пример стилизации с использованием ControlTemplates.

Расширения разметки, определенные XAML

Существует несколько расширений разметки, не относящихся к приложению WPF языка XAML, но являющихся частью спецификации XAML в качестве языка. В синтаксисе они обычно распознаются по префиксу x:, как показано в общем использовании. В реализации WPF для этих элементов языка используется тот же базовый класс MarkupExtension.

ms747254.alert_note(ru-ru,VS.90).gifПримечание.

Префикс x: используется для обычного сопоставления пространства имен XML пространства имен XAML в корневом элементе приложения или документа XAML. Например, шаблоны Microsoft Visual Studio 2005 инициируют файл XAML с помощью сопоставления x:. Можно было бы выбрать другую лексему префикса в собственном сопоставлении пространства имен XML, но в этой документации предполагается использование сопоставления x: по умолчанию как средство идентификации элементов, которые являются определенной частью пространства имен XAML, в отличие от пространства имен WPF или других произвольных пространств имен CLR или XML.

Сопоставление x:Type предоставляет объект Type для именованного типа. Это наиболее часто используется в стилях и шаблонах. Подробные сведения см. в разделе Расширение разметки x:Type.

Сопоставление x:Static создает статические значения из сущностей кода типа значения, которые непосредственно не принадлежат к типу значения свойства, но могут быть приведены к этому типу. Подробные сведения см. в разделе Расширение разметки x:Static.

Сопоставление x:Null задает null в качестве значения для свойства XAML. Подробные сведения см. в разделе Расширение разметки x:NULL.

Сопоставление x:Array обеспечивает поддержку создания общих массивов в синтаксисе XAML для случаев, когда поддержка коллекций, предоставляемая базовыми элементами и моделями элементов управления, намеренно не используется. Подробные сведения см. в разделе Расширение разметки x:Array.

Дополнительные сведения о синтаксисе расширения разметки

Классы *Extension

Поведение каждого расширения разметки определяется для обработчика XAML с помощью класса *Extension, производного от класса MarkupExtension и предоставляющего реализацию метода ProvideValue. Этот метод для каждого расширения определяет, какой объект возвращается после вычисления расширения разметки. Возвращаемый объект обычно создается в качестве экземпляра или задается с помощью различных лексем строк, передаваемых в расширение разметки.

Например, класс StaticResourceExtension предоставляет поверхностную реализацию фактического поиска ресурса, чтобы реализация его метода ProvideValue возвращала запрошенный объект. При этом в входными данными этой конкретной реализации является строка, используемая для поиска ресурса по его сопоставлению x:Key. Большая часть подробностей этой реализации неважна при использовании существующего расширения разметки.

Интерпретация класса "Extension" следующих лексем строки

Лексемы строки, следующие за идентификатором расширения разметки и по-прежнему заключенные в фигурные скобки, интерпретируются обработчиком XAML одним из указанных ниже способов.

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

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

    ms747254.alert_note(ru-ru,VS.90).gifПримечание.

    Обработчик XAML должен вызвать конструктор, который соответствует числу аргументов числа пар. По этой причине, если реализуется пользовательское расширение разметки, не предоставляйте несколько параметров с одинаковым числом аргументов: если существует несколько конструкторов расширения разметки с одинаковым числом параметров, поведение не определено.

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

  • Если имеется параллельный результат между поведением конструктора и поведением установки свойства в расширении разметки, не имеет значения, какое поведение использовать. Обычно пары свойство=значение используются для расширений разметки, которые имеют несколько устанавливаемых свойств, поскольку это делает разметку более продуманной и меньше вероятность случайно перепутать параметры конструктора (когда указываются пары свойство=значение, эти свойства могут быть в любом порядке). Кроме того, нет никакой гарантии, что расширение разметки предоставляет параметр конструктора, который задает каждое из его устанавливаемых свойств. Например, Binding является расширением разметки с множеством свойств, устанавливаемых с помощью расширения в форме свойство=значение, однако Binding поддерживает только два конструктора: конструктор по умолчанию и тот, который задает начальный путь.

Использование литеральных фигурных скобок с помощью escape-последовательностей

Обработка атрибута в обработчике XAML использует фигурные скобки в качестве индикаторов расширения разметки. Также, возможно, понадобится создать значение атрибута, содержащее литеральную фигурную скобку. Для этого необходимо ввести escape-последовательность, которая представляет собой пустую пару фигурных скобок, следующую за литеральной фигурной скобкой. См. раздел {} Escape-последовательность/расширение разметки.

Синтаксис вложенных расширений

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

<Setter Property="Background"

Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />

Дополнительные сведения о расширениях разметки и синтаксисе элементов свойств

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

Большинство расширений разметки при использовании в синтаксисе элемента объекта для заполнения элемента свойства не будет иметь содержимого или какого-либо последующего синтаксиса элемента свойства, и, таким образом, будет закрыт тег элемента объекта, и дочерние элементы не будут предоставлены. Всякий раз, когда обработчик XAML обнаруживает элемент объекта, вызывается конструктор класса для создания экземпляра объекта, созданного из разобранного элемента. Класс расширения разметки не отличается; поэтому при необходимости использования расширения разметки в синтаксисе элемента объекта нужно предоставить конструктор по умолчанию. Некоторые существующие расширения разметки имеют по крайней мере одно обязательное значение свойства, которое должно быть указано для эффективной инициализации, и в таком случае это значение обычно передается в качестве атрибута свойства элемента объекта. На страницах Возможности пространства имен языка XAML (x:) и Пространство имен WPF расширения XAML описаны расширения разметки, имеющие обязательные свойства (и имена обязательных свойств). На этих страницах также указано, разрешен ли для конкретных расширений разметки синтаксис элемента объекта или синтаксис атрибута. Важным случаем является расширение Расширение разметки x:Array, которое не поддерживает синтаксис атрибута, так как должно быть указано содержимое этого массива. Содержимое массива обрабатывается как общие объекты, поэтому не существует реального преобразователя типа по умолчанию для атрибута. Кроме того, для Расширение разметки x:Array требуется параметр Type.

См. также

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

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

Ссылки

Расширение разметки StaticResource

Привязка расширения разметки

Расширение разметки DynamicResource

Расширение разметки x:Type

Другие ресурсы

Возможности пространства имен языка XAML (x:)

Пространство имен WPF расширения XAML