Содержание
Расширение разметки — это понятие, относящееся непосредственно к языку XAML. До сих пор мы использовали возможности XAML для описания различных элементов приложения практически также, как и обычный XAML — все значения атрибутов и свойств у нас представляли собой либо строки, либо значения, которые могут быть приведены к строковому представлению. Расширения разметки обрабатываются иначе, чем обычные атрибуты в XAML.
Расширение разметки XAML: синтаксис
Синтаксис расширения разметки выглядит следующим образом:
Имя_разметки — это имя типа (класса) расширения. Аргументы перечисленные через запятую, выступают параметрами конструктора класс расширения разметки.
Если расширение разметки применяется для задания значения атрибута, то используется следующая конструкция:
<Элемент Атрибут="{имя_расширения аргументы}"/>
Для использования расширения разметки необходимо знать классы, выступающие в качестве расширений.
Расширение разметки XAML: основные классы
В пространстве имен XAML, подключаемом по умолчанию, определены следующие классы для расширений разметки:
| Класс | Описание |
StaticResource |
Поддерживает ссылки на статические ресурсы. Значение свойства замещается значением статического ресурса. |
DynamicResource |
Поддерживает ссылки на динамические ресурсы. Предоставляет значение для свойства, отложенной до времени получения ссылки на ресурс |
Binding |
Поддерживает привязку данных, которая определяет значение для свойства с помощью универсальных средств выполнения |
RelativeSource |
Обеспечивает особую форму привязки шаблонов, при которой значение свойства берется из базового шаблона |
TemplateBinding |
Особый случай Binding, который поддерживает шаблоны элемента управления в XAML и возможное их использование в среде выполнения |
Со всеми этими классами мы более подробно познакомимся в отдельных частях руководства. Кроме этого, по умолчанию, в XAML также определены следующие расширения разметки:
x:Typeпредоставляет Type объект для именованного типа. Это средство наиболее часто используется в стилях и шаблонах.x:Staticсоздает статические значения.x:Nullуказываетnullкак значение для свойства и может использоваться для атрибутов или значений элементов свойств.x:Arrayобеспечивает поддержку создания общих массивов в синтаксисе XAML для случаев, когда поддержка коллекций, предоставляемая базовыми элементами WPF и моделями элементов управления, намеренно не используется.
Чтобы продемонстрировать действие расширений разметки, рассмотрим несколько примеров их использования в приложении WPF
Примеры использования расширений разметки в XAML
x:Static
Расширение разметки x:Static обеспечивает ссылку на статический член нужного типа. Синтаксис использования этого расширения разметки следующий:
Атрибут={x:Static префикс:Имя_типа.Имя_статического_члена}
Допустим, нашему приложению WPF необходимо вывести на экран значение числа Пи. Как мы прекрасно знаем, это значение располагается в статическом классе Math. Напишем следующий код MainWindow.xaml:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<Label Content="{x:Static sys:Math.PI}"
FontSize="64"/>
</StackPanel>
</Window>
Вначале, мы подключаем пространство имен .NET System, в котором и содержится класс Math:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
для этого пространства имен мы используем префикс sys. Далее, мы используем расширение разметки x:Static, чтобы вывести значение числа Пи в текст метки Label:
<Label Content="{x:Static sys:Math.PI}" FontSize="64"/>
В визуальном редакторе WPF мы увидим:
В этом примере стоит особо отметить, что расширение разметки x:Static предоставляет нам доступ к члену определенного типа. Важность этого замечания вы почувствуете, если попытаетесь переписать пример следующим образом:
<TextBlock Text="{x:Static sys:Math.PI}"/>
В этом случае, вы увидите следующую ошибку:
Дело в том, что элемент TextBlock может принимать в качестве значения для свойства Text только строки, в то время как Label в свойстве Content может содержать любой тип данных, так как Content имеет тип object. Поэтому, при использовании x:Static всегда стоит проверять какой тип данных имеет статически член и какой тип данных имеет свойство элемента, которому мы пытаемся присвоить значение, используя расширение разметки.
StaticResource
В приложениях могут встречаться какие-либо значения, которые не имеет смысла держать отдельно, например, в базе данных. Это могут быть какие-то неизменяемые числовые значения, стили оформления элементов управления и так далее. Используя расширения разметки мы можем определять такие значения в документе XAML и получать к ним, при необходимости, доступ. Для этого в XAML можно определять словари ресурсов. Например:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<sys:String x:Key="text">Строка из ресурсов</sys:String>
<Color R="#00" G="#00" B="#FF" A="#FF" x:Key="color"/>
<sys:Double x:Key="size">68</sys:Double>
</ResourceDictionary>
</Window.Resources>
<StackPanel>
<TextBlock FontSize="{StaticResource size}" Text="{StaticResource text}">
<TextBlock.Foreground>
<SolidColorBrush Color="{StaticResource color}"/>
</TextBlock.Foreground>
</TextBlock>
</StackPanel>
</Window>
В этом примере мы настраиваем оформление текста в элементе TextBlock, используя словарь ресурсов и расширение разметки StaticResource. Для каждого ресурса в словаре ResourceDictionary мы определяем свой ключ, используя атрибут x:Key и, затем, используем значение этого ключа в расширении разметки StaticResource. В визуальном конструкторе WPF мы увидим следующий текст:
Итого
Расширение разметки — это понятие, относящееся непосредственно к языку XAML. В XAML WPF, по умолчанию, подключается пространство имен в котором содержатся классы расширений разметки, позволяющие производить какие-либо дополнительные действия, например, получать значение для свойства из статического члена или из словаря ресурсов.

