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


Терминология синтаксиса XAML

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

В этом разделе определяются термины, которые используются для описания элементов синтаксиса Язык XAML (Extensible Application Markup Language). Эти термины часто используются в данном пакете Пакет средств разработки программного обеспечения (пакет SDK). Этот раздел расширяет базовую терминологию, представленную в разделе Общие сведения о XAML.

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

  • Основа терминологии синтаксиса XAML
  • Синтаксис элемента объекта
  • Синтаксис атрибута
  • Синтаксис элемента свойства
  • Синтаксис содержимого XAML
  • Вложенные свойства
  • Вложенные события
  • Пространства имен XML
  • Расширения разметки
  • Необязательное и не рекомендуемое использование XAML
  • Связанные разделы

Основа терминологии синтаксиса XAML

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

Синтаксис элемента объекта

Синтаксис элемента объекта является синтаксисом разметки языка XAML, который создает экземпляр класса среды среда CLR (common language runtime) или структуру посредством объявления элемента XML. Этот синтаксис похож на синтаксис элемента других языков разметки, например HTML. Синтаксис элемента объекта начинается с левой угловой скобки (<), за которой следует непосредственно имя типа создаваемого класса или структуры. После имени типа может следовать несколько пробелов, а также может быть объявлено несколько атрибутов для элемента объекта с одним или несколькими пробелами, отделяющими каждую пару "имя="значение"". Наконец, должно выполняться одно из следующих условий.

  • Элемент и тег должны быть закрыты косой чертой (/), стоящей непосредственно перед правой угловой скобкой (>).

  • Открывающий тег должен быть закрыт правой угловой скобкой (>). За открывающим тегом могут следовать другие элемента объектов, элементы свойств или внутренний текст. Содержимое, которое может здесь размещаться, обычно ограничивается объектной моделью элемента; см. подраздел "Синтаксис содержимого" в этом разделе. Также для элемента объекта обязательно должен присутствовать эквивалентный закрывающий тег при правильном вложении и балансе с другими открывающими и закрывающими парами тегов.

В следующем примере показан синтаксис элемента объекта, который создает новый экземпляр класса Button, а также определяет атрибут Name и значение этого атрибута:

<Button Name="CheckoutButton"/>

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

<TextBox>This is a Text Box</TextBox>

Синтаксис атрибута

Синтаксис атрибута является синтаксисом разметки XAML, который задает значение свойства или имя обработчика событий посредством объявления атрибута в элементе. Этот элемент всегда объявляется в составе синтаксиса элемента объекта. Имя атрибута должно соответствовать имени члена среды CLR свойства или события. Имя атрибута находится перед оператором присвоения (=). Значение атрибута должно быть строкой, заключенной в двойные кавычки ('').

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

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

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

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

  3. Если преобразователь TypeConverter не существует, выполняется попытка прямого преобразования в тип свойства. Этот конечный уровень является прямым преобразованием между простыми типами или проверкой имен в перечислении (которые возвращают совпадающие значения).

Например, применяя предыдущую разметку, следующий пример является синтаксисом атрибута, используемого для присвоения строкового значения свойству Name:

<Button Name="CheckoutButton"/>

Свойство Name является членом таблицы для класса Button. Класс Button наследует от класса FrameworkElement, определяющего свойство Name.

Обработка значений атрибутов

Строковое значение, содержащееся в открывающих и закрывающих кавычках, обрабатывается обработчиком XAML. Поведение обработчика по умолчанию для свойств определяется типом базового свойства CLR. Если свойство является типом-примитивом, тогда значение атрибута назначается с учетом неявного преобразования строки в соответствующий тип-примитив. Если свойство является перечислением, тогда строка обрабатывается как имя, определяемое перечислением, и возвращается совпадающее значение перечисления. Если свойство не является типом-примитивом или перечислением, тогда значение атрибута должно обрабатываться преобразователем типов, объявленным для самого свойства или для конечного типа. Преобразователь типов должен обеспечивать преобразование, которое принимает строку и возвращает результат в виде экземпляра типа базового свойства CLR. Этап преобразования может также быть отложен посредством расширения разметки.

Значения атрибутов перечисления

Значения перечисления в XAML в действительности обрабатываются собственными методами структуры Enum.

Для значений перечисления nonflag собственное поведение состоит в обработке строки значения атрибута и разрешении его в одно из значений перечисления. Не задавайте перечисление в формате Перечисление.Значение, как в коде. Вместо этого укажите только Значение, а Перечисление неявно определяется типом задаваемого свойства. Если указать атрибут в форме Перечисление.Значение, он будет разрешен неправильно.

Для перечислений flagwise поведение основано на методе Enum.Parse. Можно указать несколько значений для перечисления flagwise, разделяя каждое значение запятой. Однако нельзя объединять значения перечисления, которые не являются flagwise. Например, нельзя использовать синтаксис с запятой, чтобы попытаться создать объект Trigger, обрабатывающий несколько условий перечисления nonflag:

<!--This will not compile, because Visibility is not a flagwise enumeration.-->
...
<Trigger Property="Visibility" Value="Collapsed,Hidden">
  <Setter ... />
</Trigger>
...

Перечисления flagwise, которые поддерживают атрибуты, устанавливаемые в XAML, очень редко встречаются в приложении WPF. Однако одним таким перечислением является StyleSimulations. Можно, например, использовать синтаксис атрибутов flagwise, разделенных запятой, чтобы изменить пример из раздела "Примечания" для класса Glyphs; атрибут StyleSimulations = "BoldSimulation" может стать свойством StyleSimulations = "BoldSimulation,ItalicSimulation". KeyBinding.Modifiers является другим свойством, где можно указать несколько значений перечисления. Однако это свойство является особым случаем, поскольку перечисление ModifierKeys поддерживает свой собственный преобразователь типов. Преобразователь типов для модификаторов использует знак плюс (+) в качестве разделителя вместо запятой (,), чтобы в разметке поддерживался более традиционный синтаксис представления сочетания клавиш, например "CTRL + ALT".

Ссылки на имя члена свойства и события

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

Можно также ссылаться на вложенное свойство или событие, независимо от содержащего элемента объекта.

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

Имена свойств иногда предоставляются в качестве значения атрибута, а не имени атрибута, и это имя свойства может также включать квалификаторы, такие как свойство, заданное в форме ownerType.dependencyPropertyName. Этот сценарий является наиболее распространенным при написании стилей или шаблонов на языке XAML. Правила обработки имен свойств, предоставленных в виде значения атрибута, различаются; они управляются типом устанавливаемого свойства и некоторыми контекстными факторами, такими как объект, принадлежащий к целевому типу, — стиль или шаблон. Подробные сведения см. в разделе Стилизация и использование шаблонов.

Другим использованием имен свойств является описание значением атрибута отношения "свойство-свойство". Эта функция используется для привязки данных и раскадровки целей и активируется классом PropertyPath и его преобразователем типов. Более полное описание семантики поиска см. в разделе Синтаксис PropertyPath XAML.

Синтаксис элемента свойства

Синтаксис элемента свойства является синтаксисом, который несколько отличается от основного синтаксиса XML. В XML значение атрибута фактически является строкой с единственно возможным значением, которое указывается, когда используется формат кодировки строки. В XAML можно назначить другие элементы объектов, которые будут значениями свойства. Эта возможность поддерживается синтаксисом элемента свойства. Вместо свойства, указанного как атрибут в теге элемента, свойство задается с помощью открывающего тега элемента в форме elementTypeName.PropertyName, указывается значение свойства и затем закрывается элемент свойства.

Этот синтаксис начинается с левой угловой скобки (<), за которой непосредственно следует имя типа класса или структуры, в котором содержится синтаксис элемента свойства. Далее непосредственно следует точка (.), затем имя свойства, которое должно существовать в таблице членов указанного типа, затем правая угловая скобка (>). Значение, присваиваемое свойству, содержится в элементе свойства. Обычно значение дается в качестве одного или нескольких элементов объекта, поскольку указание объектов как значений является сценарием, для которого в первую очередь предназначен синтаксис элемента свойства. Наконец, должен присутствовать эквивалентный закрывающий тег, определяющий то же сочетание elementTypeName.propertyName, при правильном вложении и балансе с другими тегами элемента. Например, ниже приведен синтаксис элемента свойства ContextMenu объекта Button.

<Button>
  <Button.ContextMenu>
    <ContextMenu>
      <MenuItem Header="1">First item</MenuItem>
      <MenuItem Header="2">Second item</MenuItem>
    </ContextMenu>
  </Button.ContextMenu>
  Right-click me!</Button>

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

Элемент свойства не представлен в логическом дереве. Элемент свойства — это лишь отдельный синтаксис для установки свойства, а не элемент, который имеет экземпляр или резервный объект.

Синтаксис элемента свойства для типов коллекций

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

Если тип свойства является коллекцией, тогда неявно определяемый тип коллекции не требуется указывать в разметке. Вместо этого элементы, которые должны стать элементами коллекции, указываются в виде одного или нескольких дочерних элементов элемента свойства типа коллекции. Каждый такой элемент во время загрузки приводится к объекту и добавляется в коллекцию, с помощью вызова метода Add неявной коллекции. Например, свойство Triggers объекта Style получает специализированный тип коллекции TriggerCollection. Однако не обязательно создавать экземпляр TriggerCollection в разметке. Вместо этого укажите один или несколько элементов Trigger в качестве элементов в элементе свойства Style.Triggers, где Trigger (или производный класс) является ожидаемым типом элемента для строго типизированного и неявного класса TriggerCollection.

<Style x:Key="SpecialButton" TargetType="{x:Type Button}">
  <Style.Triggers>
    <Trigger Property="Button.IsMouseOver" Value="true">
      <Setter Property = "Background" Value="Red"/>
    </Trigger>
    <Trigger Property="Button.IsPressed" Value="true">
      <Setter Property = "Foreground" Value="Green"/>
    </Trigger>
  </Style.Triggers>
</Style>

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

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

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

Универсальные интерфейсы списков и словарей (IList<T> и IDictionary<TKey, TValue>) не поддерживаются для обнаружения коллекции обработчиком XAML WPF. Тем не менее можно использовать класс List<T> как базовый класс, так как он непосредственно реализует IList, или Dictionary<TKey, TValue> как базовый класс, потому что он непосредственно реализует IDictionary.

Синтаксис содержимого XAML

Синтаксис содержимого XAML является синтаксисом, который поддерживается только для классов, определяющих в своем объявлении атрибут ContentPropertyAttribute. Для атрибута ContentPropertyAttribute требуются параметры, указывающие свойство по имени, которое определено как свойство содержимого для данного типа элемента (включая производные классы). Свойство, таким образом, назначается как свойство содержимого XAML элемента. При обработке обработчиком XAML все дочерние элементы и внутренний текст, найденные между открывающим и закрывающим тегами элемента, будут назначены как значение этого свойства содержимого XAML. Пользователю разрешено указать элементы свойства для свойства содержимого, если требуется сделать явной разметку. Этот метод имеет случайное значение, чтобы внести ясность в разметку или указать ее стиль, но обычно целью свойства содержимого является упрощение разметки, чтобы можно было непосредственно вложить элементы, интуитивно связанные отношением "родительский-дочерний". Теги элемента свойства для других свойств в элементе не заданы как "содержимое"; они в первую очередь обрабатываются в рабочем потоке синтаксического анализатора и не рассматриваются как "содержимое".

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

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

Синтаксис содержимого для типов коллекций

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

<Page
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  >
  <StackPanel>
    <Button>Button 1</Button>
    <Button>Button 2</Button>
    <Button>Button 3</Button>
  </StackPanel>
</Page>

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

Смешивание элементов свойств и элементов объектов в объекте со свойством содержимого

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

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

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

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

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

Вложенные свойства используют синтаксис, который внешне напоминает синтаксис элемента свойства, в котором также указывается сочетание TypeName.PropertyName. Существуют два важных различия:

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

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

Вложенные события

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

Пространства имен XML

Ни в одном из предыдущих примеров синтаксиса не указано пространство имен, отличное от пространства имен по умолчанию. В обычных приложениях WPF по умолчанию задано пространство имен WPF. Можно указать пространство имен, отличное от пространства имен по умолчанию, и по прежнему использовать фактически тот же синтаксис, но в любом месте, где именуется класс, который недоступен в пространстве имен по умолчанию, имя этого класса должно начинаться с префикса пространства имен XML, который используется для сопоставления соответствующего пространства имен среды CLR. Например, <custom:MyElement/> представляет собой синтаксис элемента объекта для создания экземпляра класса MyElement, где пространство CLR, содержащее этот класс (и, возможно, внешняя сборка, содержащая это пространство имен) было предварительно сопоставлено с префиксом custom.

Дополнительные сведения о пространствах имен XML и XAML см. в разделе Пространства имен XAML и сопоставление пространств имен.

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

XAML определяет программную сущность расширение разметки, которая позволяет выйти за рамки обычной обработки атрибутов или элементов объектов процессором XAML и переложить обработку на вспомогательный класс. Реализация обработчика XAML в приложении WPF использует абстрактный класс MarkupExtension в качестве базы для всех поддерживаемых приложением WPF расширений разметки. Знаком, указывающим обработчику XAML расширение разметки при использовании синтаксиса атрибута, является открывающая фигурная скобка ({), за которой следует любой знак, отличный от закрывающей фигурной скобки (}). Первая строка, следующая за открывающей фигурной скобкой, должна ссылаться на класс, который обеспечивает отдельное поведение расширения, и в этой ссылке можно пропустить подстроку "Extension", если эта подстрока является частью истинного имени класса. После этого может использоваться один пробел, и затем каждый последующий знак используется в качестве входных данных реализации расширения, вплоть до закрывающей фигурной скобки. Расширения разметки в приложении WPF предназначены, главным образом, для предоставления ссылок на другие существующие объекты или для предоставления отложенных ссылок на объекты, которые будут вычисляться во время выполнения, используя при этом синтаксис атрибута. Например, простая привязка данных выполняется путем указания расширения разметки {Binding} вместо типа значения, которое обычно должно принимать данное свойство. Большинство расширений разметки включает синтаксис атрибута для свойств, в которых синтаксис атрибута иначе был бы невозможен. Например, объект Style является относительно сложным ссылочным типом, содержащим несколько других свойств, каждое из которых также принимает не примитивы, а объекты по ссылке. Но стили обычно создаются как ресурсы, и ссылка на них осуществляется с помощью одного из двух расширений разметки, запрашивающих ресурс. Расширение откладывает вычисление значения свойства до выполнения поиска ресурса и включает предоставление значения свойства Style, принимающего объект типа Style, в синтаксисе атрибута следующим образом:

<Button Style="{StaticResource MyStyle}">My button</Button>

Здесь элемент StaticResource определяет класс StaticResourceExtension, предоставляющий реализацию расширения разметки. Следующая строка MyStyle используется в качестве входных данных для нестандартного конструктора StaticResourceExtension, где параметр, принимаемый из строки расширения, объявляет запрашиваемый объект ResourceKey. MyStyle должно быть значением Атрибут x:Key объекта Style, объявленного как ресурс. Использование Расширение разметки StaticResource требует, чтобы ресурс использовался для предоставления значения свойства Style через логику поиска статических ресурсов во время загрузки.

Дополнительные сведения о расширениях разметки см. в разделе Расширения разметки и XAML. Ссылки на расширения разметки и другие программные средства XAML см. в разделах Возможности пространства имен языка XAML (x:) и Пространство имен WPF расширения XAML.

Необязательное и не рекомендуемое использование XAML

Необязательное использование элемента свойства

К необязательному использованию элементов свойств относится явное объявление свойств содержимого элементов, которые обработчик XAML рассматривает как неявные. Например, при объявлении содержимого объекта Menu можно явно объявить коллекцию Items объекта Menu в виде тега элемента свойства <Menu.Items> и поместить каждый элемент MenuItem в элементы <Menu.Items>, вместо использования неявного поведения обработчика XAML, в котором все дочерние элементы из объекта Menu должны быть классом MenuItem и помещены в коллекцию Items. Иногда необязательное использование помогает визуально уточнить объектную структуру, представленную в разметке. Или иногда использование явного элемента свойства может помочь избежать технически функциональной, но визуально непонятной разметки, например — вложенные расширения разметки в значении атрибута.

Атрибуты с указанием полного имени typeName.memberName

Форма typeName.memberName для атрибута фактически работает более универсально, чем в случае перенаправляемого события, но в других приложениях эта форма является избыточной, и ее следует избегать, если только она не используется в целях повышения чистоты стиля и удобочитаемости разметки. В следующем примере каждая из трех ссылок на атрибут Background полностью эквивалентна:

<Button Background="Blue">Background</Button>
<Button Button.Background="Blue">Button.Background</Button>
<Button Control.Background="Blue">Control.Background</Button>

Ссылка Button.Background работает, поскольку полный поиск этого свойства в объекте Button является успешным (свойство Background было наследовано от свойства Control) и Button является классом элемента объекта или базовым классом. Ссылка Control.Background работает, поскольку класс Control фактически определяет свойство Background и Control является базовым классом для класса Button.

Однако следующий пример формы typeName.memberName не работает, и поэтому помечен маркерами комментария:

<!--<Button Label.Background="Blue">Does not work</Button> -->

Label является другим классом, производным от Control, и если бы свойство Label.Background было указано внутри элемента объекта Label, то это использование могло бы работать. Однако поскольку Label не является классом или базовым классом для Button, указанное поведение обработчика XAML обрабатывает Label.Background как вложенное свойство. Label.Background не является присоединенным свойством, и это использование приводит к сбою.

Элементы свойства baseTypeName.memberName

Точно так же, как форма typeName.memberName работает для синтаксиса атрибута, синтаксис baseTypeName.memberName работает для синтаксиса элемента свойства. Например, следующий синтаксис работает:

<Button>Control.Background PE
  <Control.Background>
    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
      <GradientStop Color="Yellow" Offset="0.0" />
      <GradientStop Color="LimeGreen" Offset="1.0" />
    </LinearGradientBrush>
    </Control.Background>
</Button>

Здесь элемент свойства задан как Control.Background, даже если элемент свойства содержится в Button.

Но так же, как форма typeName.memberName для атрибутов, форма baseTypeName.memberName является неудовлетворительным стилем в разметке, и по этой причине ее следует избегать.

См. также

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

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

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

TypeConverters и XAML

Язык XAML и пользовательские классы

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

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

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