Шаблоны элементов управления
Вы можете настроить визуальную структуру и визуальное поведение элемента управления, создав шаблон элемента управления в среде XAML. У элементов управления много свойств, таких как Background, Foreground и FontFamily, которые можно задать, чтобы указать различные аспекты вида элемента управления. Однако настройка этих свойств позволяет вносить ограниченные изменения. Вы можете указать дополнительные настройки, создав шаблон с помощью класса ControlTemplate. Здесь мы покажем, как создать ControlTemplate для настройки вида элемента управления CheckBox.
Важные API: класс ControlTemplate и свойство Control.Template
Пример пользовательского шаблона элемента управления
По умолчанию элемент управления CheckBox помещает свое содержимое (строку или объект рядом с CheckBox) справа от поля выбора, а флажок указывает, что пользователь выбрал CheckBox. Эти характеристики представляют визуальную структуру и визуальное поведение CheckBox.
Здесь CheckBox использует шаблон по умолчанию ControlTemplate, показанный в состояниях Unchecked
, Checked
и Indeterminate
.
Эти характеристики можно изменить, создав ControlTemplate для CheckBox. Например, если содержимое поля флажка должно быть ниже поля выбора, а для указания того, что пользователь установил флажок, следует использовать X. Эти характеристики указываются в ControlTemplate элемента управления CheckBox.
Чтобы использовать пользовательский шаблон с элементом управления, ControlTemplate назначается свойству Template элемента управления. Вот CheckBox, использующий ControlTemplateпод названием CheckBoxTemplate1
. Мы покажем код XAML (Extensible Application Markup Language) для ControlTemplate в следующем разделе.
<CheckBox Content="CheckBox" Template="{StaticResource CheckBoxTemplate1}" IsThreeState="True" Margin="20"/>
Вот как этот класс CheckBox выглядит в состояниях Unchecked
, Checked
и Indeterminate
после применения нашего шаблона.
Указание визуальной структуры элемента управления
При создании ControlTemplate мы объединяем объекты FrameworkElement, чтобы создать единый элемент управления. У ControlTemplate должен быть только один FrameworkElement в качестве корневого элемента. Корневой элемент обычно содержит другие объекты FrameworkElement. Такое сочетание объектов формирует визуальную структуру элемента управления.
Данный код XAML создает ControlTemplate для CheckBox, указывающий, что содержимое элемента управления находится под полем выбора. Корневой элемент — Border. Этот пример предлагает Path создать X, указывающий на то, что пользователь выбрал CheckBox, и Ellipse, указывающий на неопределенное состояние. Обратите внимание, что свойству Opacity задано значение 0 в Path и Ellipse, так что по умолчанию последние не выводятся.
TemplateBinding связывает значение свойства в шаблоне элемента управления и значение какого-либо другого предоставленного свойства элемента управления-шаблона. TemplateBinding может использоваться только в пределах определения ControlTemplate в XAML. См. подробнее в разделе Расширение разметки TemplateBinding.
Примечание
Начиная с Windows 10, версия 1809 (SDK 17763), вы можете использовать расширения разметки x:Bind вместе с TemplateBinding. См. подробнее в разделе Расширение разметки TemplateBinding.
<ControlTemplate x:Key="CheckBoxTemplate1" TargetType="CheckBox">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Rectangle x:Name="NormalRectangle" Fill="Transparent" Height="20" Width="20"
Stroke="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}"
UseLayoutRounding="False"/>
<!-- Create an X to indicate that the CheckBox is selected. -->
<Path x:Name="CheckGlyph"
Data="M103,240 L111,240 119,248 127,240 135,240 123,252 135,264 127,264 119,257 111,264 103,264 114,252 z"
Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
FlowDirection="LeftToRight"
Height="14" Width="16" Opacity="0" Stretch="Fill"/>
<Ellipse x:Name="IndeterminateGlyph"
Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
Height="8" Width="8" Opacity="0" UseLayoutRounding="False" />
<ContentPresenter x:Name="ContentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}" Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Border>
</ControlTemplate>
Указание визуального поведения элемента управления
Визуальное поведение описывает внешний вид элемента управления в определенных состояниях. У элемента управления CheckBox есть три состояния выставления: Checked
, Unchecked
и Indeterminate
. Значение свойства IsChecked определяет состояние CheckBox, а состояние последнего определяет, что появляется в поле.
В приведенной ниже таблице перечислены возможные значения IsChecked, соответствующие состояния CheckBox и представление CheckBox.
Значение IsChecked | Состояние CheckBox | Вид CheckBox |
---|---|---|
true | Checked |
Содержит X. |
false | Unchecked |
Пусто. |
null | Indeterminate |
Содержит кружок. |
Для указания представления элемента управления, когда он находится в определенном состоянии, используйте объекты VisualState. Объект VisualState содержит класс Setter или Storyboard, меняющий представление элементов в классе ControlTemplate. Когда элемент управления переходит в состояние, указанное в свойстве VisualState.Name, применяются изменения свойств в Setter или Storyboard. Когда элемент управления выходит из этого состояния, изменения удаляются. Мы добавляем объекты VisualState к объектам VisualStateGroup. Мы добавляем объекты VisualStateGroup к подключенному свойству VisualStateManager.VisualStateGroups, установленному на корневом элементе FrameworkElement шаблона ControlTemplate.
Приведенный XAML-код показывает объекты VisualState для состояний Checked
, Unchecked
и Indeterminate
. Данный пример задает присоединенное свойство VisualStateManager.VisualStateGroups для Border, который является корневым элементом ControlTemplate. VisualStateChecked
указывает, что значение Opacityпути с именем CheckGlyph
(как показано в предыдущем примере) равно 1. VisualStateIndeterminate
указывает, что значение Opacity имени эллипсаIndeterminateGlyph
равно 1. VisualStateUnchecked
не имеет метода задания или раскадровки, поэтому элемент CheckBox возвращает свой внешний вид по умолчанию.
<ControlTemplate x:Key="CheckBoxTemplate1" TargetType="CheckBox">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter Target="CheckGlyph.Opacity" Value="1"/>
</VisualState.Setters>
<!-- This Storyboard is equivalent to the Setter. -->
<!--<Storyboard>
<DoubleAnimation Duration="0" To="1"
Storyboard.TargetName="CheckGlyph" Storyboard.TargetProperty="Opacity"/>
</Storyboard>-->
</VisualState>
<VisualState x:Name="Unchecked"/>
<VisualState x:Name="Indeterminate">
<VisualState.Setters>
<Setter Target="IndeterminateGlyph.Opacity" Value="1"/>
</VisualState.Setters>
<!-- This Storyboard is equivalent to the Setter. -->
<!--<Storyboard>
<DoubleAnimation Duration="0" To="1"
Storyboard.TargetName="IndeterminateGlyph" Storyboard.TargetProperty="Opacity"/>
</Storyboard>-->
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Rectangle x:Name="NormalRectangle" Fill="Transparent" Height="20" Width="20"
Stroke="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}"
UseLayoutRounding="False"/>
<!-- Create an X to indicate that the CheckBox is selected. -->
<Path x:Name="CheckGlyph"
Data="M103,240 L111,240 119,248 127,240 135,240 123,252 135,264 127,264 119,257 111,264 103,264 114,252 z"
Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
FlowDirection="LeftToRight"
Height="14" Width="16" Opacity="0" Stretch="Fill"/>
<Ellipse x:Name="IndeterminateGlyph"
Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
Height="8" Width="8" Opacity="0" UseLayoutRounding="False" />
<ContentPresenter x:Name="ContentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}" Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Border>
</ControlTemplate>
Чтобы лучше понять, как работают объекты VisualState, давайте рассмотрим, что происходит, когда CheckBox переходит из состояния Unchecked
в состояние Checked
, затем в состояние Indeterminate
и обратно в состояние Unchecked
. Вот эти переходы.
Смена состояния | Что происходит | Представление CheckBox по завершении смены состояния |
---|---|---|
С Unchecked на Checked . |
Применяется значение Checked SettervisualState, поэтому значение OpacityCheckGlyph равно 1. |
Отображается X. |
С Checked на Indeterminate . |
Применяется значение Indeterminate SettervisualState, поэтому значение OpacityIndeterminateGlyph равно 1. Значение Checked SettervisualState удаляется, поэтому значение OpacityCheckGlyph равно 0. |
Отображается круг. |
С Indeterminate на Unchecked . |
Значение Indeterminate SettervisualState удаляется, поэтому значение OpacityIndeterminateGlyph равно 0. |
Не отображается ничего. |
Подробнее о том, как создавать визуальные состояния элементов управления, в частности о том, как использовать класс Storyboard и типы анимации см. в разделе Раскадрованные анимации для визуальных состояний.
Используйте средства для упрощения работы с темами
Чтобы быстро применить темы к своим элементам управления, щелкните элемент управления правой кнопкой мыши в структуре документа Microsoft Visual Studio XAML и выберите команду Изменить тему или Изменить стиль (в зависимости от элемента управления). Затем можно применить существующую тему, выбрав команду Применить ресурс, или определить новую командой Создать пустой.
Элементы управления и специальные возможности
При создании нового шаблона для элемента управления помимо возможного изменения его поведения и внешнего вида вы, вероятно, также измените то, как элемент управления заявляет о себе платформам специальных возможностей. Приложения для Windows поддерживают инфраструктуру автоматизации пользовательского интерфейса Майкрософт для включения специальных возможностей. Все элементы управления по умолчанию и их шаблоны поддерживают общие типы и схемы элементов управления автоматизацией пользовательского интерфейса, соответствующие назначению и функции элемента управления. Эти типы и схемы элементов управления интерпретируются такими клиентами автоматизации пользовательского интерфейса, как клиенты специальных возможностей. И это обеспечивает доступ к элементу управления в составе более масштабного доступного пользовательского интерфейса приложения.
Чтобы выделить базовую логику элементов управления, а также соответствовать ряду архитектурных требований автоматизации пользовательского интерфейса, классы элементов управления включают поддержку специальных возможностей в отдельном классе, называемом "одноранговый элемент автоматизации". Одноранговые элементы автоматизации иногда взаимодействуют с шаблонами элементов управления, так как эти элементы автоматизации ожидают наличия в шаблонах определенных именованных частей. Благодаря этому доступны такие функции, как включение специальных возможностей при вызове действий кнопок.
Когда вы создаете совершенно новый пользовательский элемент управления, порой бывает необходимо создать помимо этого новый одноранговый элемент автоматизации. Дополнительную информацию см. в разделе Настраиваемые одноранговые элементы автоматизации.
Дополнительные сведения о стандартном шаблоне элемента управления
Разделы, описывающие стили и шаблоны для элементов управления XAML, показывают выдержки из аналогичных разделов краткого руководства по XAML, которые вы бы увидели, если бы использовали команды Изменить тему или Изменить стиль, описанные ранее. Каждый раздел перечисляет имена визуальных состояний, использованные ресурсы тем, а также полный код XAML для стиля, содержащего шаблон. Разделы могут стать полезным руководством, если вы уже начали изменение шаблона и хотите посмотреть, как выглядит первоначальный шаблон, либо хотите проверить, имеет ли новый шаблон все необходимые именованные визуальные состояния.
Ресурсы тем в шаблонах элементов управления
В некоторых атрибутах в примерах кода XAML вы могли заметить ссылки на ресурсы, которые используют расширение разметки {ThemeResource}. Данная технология позволяет одному шаблону элемента управления использовать разнообразные ресурсы в зависимости от того, какая из тем активна на текущий момент. Это особенно важно для кистей и цветов, поскольку основная цель тем — предоставить пользователям возможность выбора темной или светлой темы либо темы "Высокая контрастность" в применении к системе в целом. Приложения, которые используют систему на базе ресурсов XAML, могут использовать набор ресурсов, соответствующий определенной теме. Выбор темы в пользовательском интерфейсе приложения будет отражать выбор пользователем темы для всей системы в целом.
Получение примера кода
Windows developer
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по