Стили XAMLXAML styles

Платформа XAML предоставляет множество способов настройки внешнего вида приложений.You can customize the appearance of your apps in many ways by using the XAML framework. С помощью стилей вы можете настраивать свойства элементов управления и многократно использовать эти параметры, чтобы придать единообразный внешний вид нескольким элементам управления.Styles let you set control properties and reuse those settings for a consistent appearance across multiple controls.

Основные сведения о стиляхStyle basics

С помощью стилей можно превратить параметры визуальных элементов во многократно используемые ресурсы.Use styles to extract visual property settings into reusable resources. В следующем примере показаны три кнопки со стилем, задающим свойства BorderBrush, BorderThickness и Foreground.Here's an example that shows 3 buttons with a style that sets the BorderBrush, BorderThickness and Foreground properties. Применение стиля позволяет обеспечить единообразный вид элементов управления, не настраивая свойства каждого из них в отдельностиBy applying a style, you can make the controls appear the same without having to set these properties on each control separately.

Снимок экрана: три стилизованные кнопки, расположенные горизонтально.

Стиль можно определить в качестве встроенного для элемента управления на XAML или в качестве многократно используемого ресурса.You can define a style inline in the XAML for a control, or as a reusable resource. Ресурсы определяются в XAML-файле отдельной страницы, файле App.xaml или отдельном XAML-файле словаря ресурсов.Define resources in an individual page's XAML file, in the App.xaml file, or in a separate resource dictionary XAML file. Несколько приложений могут совместно использовать XAML-файл словаря ресурсов. Одна программа может использовать несколько словарей ресурсов.A resource dictionary XAML file can be shared across apps, and more than one resource dictionary can be merged in a single app. Область определения ресурсов определяет область их использования.Where the resource is defined determines the scope in which it can be used. Ресурсы, определенные на уровне страницы, доступны только для этой страницы.Page-level resources are available only in the page where they are defined. Если ресурсы с одинаковым ключом определены одновременно в файле App.xaml и в странице, ресурс страницы переопределяет ресурс в App.xaml.If resources with the same key are defined in both App.xaml and in a page, the resource in the page overrides the resource in App.xaml. Если ресурс определен в отдельном файле словаря ресурсов, то область его использования зависит от того, на что ссылается словарь ресурсов.If a resource is defined in a separate resource dictionary file, its scope is determined by where the resource dictionary is referenced.

В определении Style требуется атрибут TargetType и коллекция одного или нескольких элементов Setter.In the Style definition, you need a TargetType attribute and a collection of one or more Setter elements. Атрибут TargetType является строкой, задающей тип FrameworkElement, к которому применяется стиль.The TargetType attribute is a string that specifies a FrameworkElement type to apply the style to. Значение TargetType должно указывать производный от FrameworkElement тип, определенный средой выполнения Windows, или пользовательский тип, доступный в ссылаемой сборке.The TargetType value must specify a FrameworkElement-derived type that's defined by the Windows Runtime or a custom type that's available in a referenced assembly. Если вы попытаетесь применить стиль к элементу управления, тип которого не соответствует атрибуту TargetType этого стиля, будет выдано исключение.If you try to apply a style to a control and the control's type doesn't match the TargetType attribute of the style you're trying to apply, an exception occurs.

Для каждого элемента Setter необходимы параметры Property и Value.Each Setter element requires a Property and a Value. Эти параметры свойства показывают, к какому свойству элемента управления применяется параметр, а также значение, задаваемое для этого свойства.These property settings indicate what control property the setting applies to, and the value to set for that property. Параметр Setter.Value можно настроить с помощью синтаксиса атрибута или элемента свойства.You can set the Setter.Value with either attribute or property element syntax. В этом примере кода XAML показано, как применить стиль к показанным ранее кнопкам.The XAML here shows the style applied to the buttons shown previously. В этом коде XAML для первых двух элементов Setter используется синтаксис атрибута, а в последнем элементе Setter (для свойства BorderBrush) — синтаксис элемента свойства.In this XAML, the first two Setter elements use attribute syntax, but the last Setter, for the BorderBrush property, uses property element syntax. В примере не используется атрибут x:Key, и поэтому стиль неявно применяется к кнопкам.The example doesn't use the x:Key attribute attribute, so the style is implicitly applied to the buttons. Явное и неявное применение стилей поясняется в следующем разделе.Applying styles implicitly or explicitly is explained in the next section.

<Page.Resources>
    <Style TargetType="Button">
        <Setter Property="BorderThickness" Value="5" />
        <Setter Property="Foreground" Value="Black" />
        <Setter Property="BorderBrush" >
            <Setter.Value>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <GradientStop Color="Yellow" Offset="0.0" />
                    <GradientStop Color="Red" Offset="0.25" />
                    <GradientStop Color="Blue" Offset="0.75" />
                    <GradientStop Color="LimeGreen" Offset="1.0" />
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
</Page.Resources>

<StackPanel Orientation="Horizontal">
    <Button Content="Button"/>
    <Button Content="Button"/>
    <Button Content="Button"/>
</StackPanel>

Применение явного или неявного стиляApply an implicit or explicit style

Стиль, определенный как ресурс, можно применять к элементам управления двумя способами:If you define a style as a resource, there are two ways to apply it to your controls:

Если стиль содержит атрибут x:Key, то его можно применить к элементу управления только путем задания стиля с ключом в свойстве Style элемента управления.If a style contains the x:Key attribute, you can only apply it to a control by setting the Style property of the control to the keyed style. Стиль, не имеющий атрибута x:Key, автоматически применяется к каждому элементу управления целевого типа, если отсутствует явно заданный стиль.In contrast, a style without an x:Key attribute is automatically applied to every control of its target type, that doesn't otherwise have an explicit style setting.

Далее показаны две кнопки с явным и неявным стилем.Here are two buttons that demonstrate implicit and explicit styles.

Кнопки с явным и неявным заданием стиля.

В этом примере первый стиль содержит атрибут x:Key и имеет тип целевого объекта Button.In this example, the first style has an x:Key attribute and its target type is Button. Данный ключ задается в свойстве Style и поэтому стиль применяется явным образом.The first button's Style property is set to this key, so this style is applied explicitly. Второй стиль применяется ко второй кнопке неявно, поскольку он имеет тип целевого объекта Button, а в стиле отсутствует атрибут x:Key.The second style is applied implicitly to the second button because its target type is Button and the style doesn't have an x:Key attribute.

<Page.Resources>
    <Style x:Key="PurpleStyle" TargetType="Button">
        <Setter Property="FontFamily" Value="Segoe UI"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="Foreground" Value="Purple"/>
    </Style>

    <Style TargetType="Button">
        <Setter Property="FontFamily" Value="Segoe UI"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="RenderTransform">
            <Setter.Value>
                <RotateTransform Angle="25"/>
            </Setter.Value>
        </Setter>
        <Setter Property="BorderBrush" Value="Green"/>
        <Setter Property="BorderThickness" Value="2"/>
        <Setter Property="Foreground" Value="Green"/>
    </Style>
</Page.Resources>

<Grid x:Name="LayoutRoot">
    <Button Content="Button" Style="{StaticResource PurpleStyle}"/>
    <Button Content="Button"/>
</Grid>

Использование производных стилейUse based-on styles

Для упрощения работы со стилями и оптимизации их многократного использования можно создавать стили, производные от других стилей.To make styles easier to maintain and to optimize style reuse, you can create styles that inherit from other styles. Для создания производных стилей служит свойство BasedOn.You use the BasedOn property to create inherited styles. Производные стили должны применяться к элементу управления того же типа, к которому применяется базовый стиль, или к производному элементу управления.Styles that inherit from other styles must target the same type of control or a control that derives from the type targeted by the base style. Например, если базовый стиль применяется к элементу ContentControl, то основанные на нем стили могут применяться к элементу ContentControl или к типам, производным от ContentControl, например Button и ScrollViewer.For example, if a base style targets ContentControl, styles that are based on this style can target ContentControl or types that derive from ContentControl such as Button and ScrollViewer. Если в производном стиле не задано значение, оно наследуется от базового стиля.If a value is not set in the based-on style, it's inherited from the base style. Чтобы изменить значение базового стиля, его следует переопределить в производном стиле.To change a value from the base style, the based-on style overrides that value. В следующем примере показаны классы Button и CheckBox со стилями, производными от одного базового стиля.The next example shows a Button and a CheckBox with styles that inherit from the same base style.

Кнопки с применением производных стилей.

В базовом стиле целевым типом является ContentControl и заданы свойства Height и Width.The base style targets ContentControl, and sets the Height, and Width properties. В стилях, основанных на этом стиле, целевыми типами будут CheckBox и Button, производные от ContentControl.The styles based on this style target CheckBox and Button, which derive from ContentControl. Производные стили задают новые цвета для свойств BorderBrush и Foreground.The based-on styles set different colors for the BorderBrush and Foreground properties. (Обычно вы не отображаете рамку вокруг CheckBox.(You don't typically put a border around a CheckBox. Мы делаем это, чтобы продемонстрировать влияние на стиль.)We do it here to show the effects of the style.)

<Page.Resources>
    <Style x:Key="BasicStyle" TargetType="ContentControl">
        <Setter Property="Width" Value="130" />
        <Setter Property="Height" Value="30" />
    </Style>

    <Style x:Key="ButtonStyle" TargetType="Button"
           BasedOn="{StaticResource BasicStyle}">
        <Setter Property="BorderBrush" Value="Orange" />
        <Setter Property="BorderThickness" Value="2" />
        <Setter Property="Foreground" Value="Red" />
    </Style>

    <Style x:Key="CheckBoxStyle" TargetType="CheckBox"
           BasedOn="{StaticResource BasicStyle}">
        <Setter Property="BorderBrush" Value="Blue" />
        <Setter Property="BorderThickness" Value="2" />
        <Setter Property="Foreground" Value="Green" />
    </Style>
</Page.Resources>

<StackPanel>
    <Button Content="Button" Style="{StaticResource ButtonStyle}" Margin="0,10"/>
    <CheckBox Content="CheckBox" Style="{StaticResource CheckBoxStyle}"/>
</StackPanel>

Инструменты для удобной работы со стилямиUse tools to work with styles easily

Чтобы быстро применить стили к элементу управления, щелкните его правой кнопкой мыши в рабочей области конструирования XAML в Microsoft Visual Studio и выберите команду Изменить стиль или Изменить шаблон (в зависимости от элемента управления).A fast way to apply styles to your controls is to right-click on a control on the Microsoft Visual Studio XAML design surface and select Edit Style or Edit Template (depending on the control you are right-clicking on). Затем можно применить существующий стиль, выбрав команду Применить ресурс, или определить новый стиль командой Создать пустой.You can then apply an existing style by selecting Apply Resource or define a new style by selecting Create Empty. При создании пустого стиля можно определить его на странице, в файле App.xaml или в отдельном словаре ресурсов.If you create an empty style, you are given the option to define it in the page, in the App.xaml file, or in a separate resource dictionary.

Облегченное определение стиляLightweight styling

Переопределение системных кистей обычно выполняется на уровне страницы или приложения, и в обоих случаях переопределение цвета влияет на все элементы управления, ссылающиеся на эту кисть, а в XAML многие элементы управления могут ссылаться на одну и ту же системную кисть.Overriding the system brushes is generally done at the App or Page level, and in either case the color override will affect all controls that reference that brush – and in XAML many controls can reference the same system brush.

Снимок экрана с двумя кнопками: одна из них неактивна, а к другой применена упрощенная стилизация.

<Page.Resources>
    <ResourceDictionary>
        <ResourceDictionary.ThemeDictionaries>
            <ResourceDictionary x:Key="Light">
                 <SolidColorBrush x:Key="ButtonBackground" Color="Transparent"/>
                 <SolidColorBrush x:Key="ButtonForeground" Color="MediumSlateBlue"/>
                 <SolidColorBrush x:Key="ButtonBorderBrush" Color="MediumSlateBlue"/>
            </ResourceDictionary>
        </ResourceDictionary.ThemeDictionaries>
    </ResourceDictionary>
</Page.Resources>

Для состояний наподобие PointerOver (наведение мыши на кнопку), PointerPressed (кнопка вызвана), или Disabled (кнопка не активна).For states like PointerOver (mouse is hovered over the button), PointerPressed (button has been invoked), or Disabled (button is not interactable). Эти окончания добавляются к исходным именам облегченного оформления: ButtonBackgroundPointerOver, ButtonForegroundPointerPressed, ButtonBorderBrushDisabledи т. д. Изменение и этих кистей гарантирует, что ваши элементы управления раскрашены в соответствии с темой приложения.These endings are appended onto the original Lightweight styling names: ButtonBackgroundPointerOver, ButtonForegroundPointerPressed, ButtonBorderBrushDisabled, etc. Modifying those brushes as well, will make sure that your controls are colored consistently to your app's theme.

Размещение переопределений этих кистей на уровне App.Resources изменяет все кнопки в пределах всего приложения, а не на одной странице.Placing these brush overrides at the App.Resources level, will alter all the buttons within the entire app, instead of on a single page.

Настройка стиля для элементов управления по отдельностиPer-control styling

В других случаях необходимо изменение одного элемента управления на одной странице определенным образом без изменения других версий этого элемента управления:In other cases, changing a single control on one page only to look a certain way, without altering any other versions of that control, is desired:

Снимок экрана: три стилизованные кнопки, расположенные вертикально.

<CheckBox Content="Normal CheckBox" Margin="5"/>
<CheckBox Content="Special CheckBox" Margin="5">
    <CheckBox.Resources>
        <ResourceDictionary>
            <ResourceDictionary.ThemeDictionaries>
                <ResourceDictionary x:Key="Light">
                    <SolidColorBrush x:Key="CheckBoxForegroundUnchecked"
                        Color="Purple"/>
                    <SolidColorBrush x:Key="CheckBoxForegroundChecked"
                        Color="Purple"/>
                    <SolidColorBrush x:Key="CheckBoxCheckGlyphForegroundChecked"
                        Color="White"/>
                    <SolidColorBrush x:Key="CheckBoxCheckBackgroundStrokeChecked"  
                        Color="Purple"/>
                    <SolidColorBrush x:Key="CheckBoxCheckBackgroundFillChecked"
                        Color="Purple"/>
                </ResourceDictionary>
            </ResourceDictionary.ThemeDictionaries>
        </ResourceDictionary>
    </CheckBox.Resources>
</CheckBox>
<CheckBox Content="Normal CheckBox" Margin="5"/>

Это повлияет только на тот единственный Special CheckBox на странице, где этот элемент управления расположен.This would only effect that one “Special CheckBox” on the page where that control existed.

Изменение системных стилей, используемых по умолчаниюModify the default system styles

По возможности следует использовать стили из ресурсов XAML среды выполнения Windows, используемых по умолчанию.You should use the styles that come from the Windows Runtime default XAML resources when you can. Если вам нужно определить собственные стили, старайтесь создавать их на базе стилей по умолчанию (используйте базовые стили, как описано выше, или измените копию исходного стиля по умолчанию).When you have to define your own styles, try to base your styles on the default ones when possible (using based-on styles as explained earlier, or start by editing a copy of the original default style).

Свойство TemplateThe template property

Вы можете использовать метод задания стиля для свойства Template класса Control. По сути, сюда входит большинство типовых стилей XAML и ресурсов XAML приложения.A style setter can be used for the Template property of a Control, and in fact this makes up the majority of a typical XAML style and an app's XAML resources. Подробные сведения см. в статье Шаблоны элементов управления.This is discussed in more detail in the topic Control templates.