Стили и шаблоны

Стили

Последнее обновление: 25.11.2017

Стили применяются для создания единообразного отображения элементов, также они упрощают подключения группы ресурсов к отдельным элементам. Стили позволяют определить набор некоторых свойств и их значений, которые потом могут применяться к элементам в xaml. Стили хранятся в ресурсах и отделяют значения свойств элементов от пользовательского интерфейса. Аналогом стилей могут служить каскадные таблицы стилей (CSS), которые применяются в коде html на веб-страницах.

Допустим, у нас есть следующий код xaml:

<StackPanel x:Name="buttonsStack">
    <Button x:Name="button1" Content="Кнопка 1" Margin="10" 
		FontFamily="Verdana" Foreground="#ecf0f1" Background="#34495e" />
    <Button x:Name="button2" Content="Кнопка 2" Margin="10" 
		FontFamily="Verdana" Foreground="#ecf0f1" Background="#34495e"/>
</StackPanel>
Стили в Universal Windows Platform

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

<Page
    x:Class="BindingApp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:BindingApp"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.Resources>
        <Style x:Key="ButtonStyle" TargetType="Button" >
            <Setter Property="Control.FontFamily" Value="Verdana" />
            <Setter Property="Control.Background" Value="#34495e" />
            <Setter Property="Control.Foreground" Value="#ecf0f1" />
            <Setter Property="Control.Margin" Value="10" />
        </Style>
    </Page.Resources>
    <StackPanel x:Name="buttonsStack" >
        <Button x:Name="button1" Content="Кнопка 1"
                Style="{StaticResource ButtonStyle}" />
        <Button x:Name="button2" Content="Кнопка 2"
                Style="{StaticResource ButtonStyle}"/>
    </StackPanel>
</Page>

Результат будет тот же, однако теперь мы избегаем не нужного повторения. Более того теперь мы можем управлять всеми нужными нам свойствами как единым целым - одним стилем.

Стиль создается как ресурс с помощью объекта Style, который представляет класс Windows.UI.Xaml.Style. Как у всякого ресурса, у стиля устанавливается ключ с помощью атрибута x:Key, а также свойство TargetType - оно указывает на тип элементов, к которым применяется стиль.

Внутри стиля в коллекции Setters создаются объекты Setter. Они определяют свойства стилизации и их значения с помощью следующих атрибутов:

  • Property: указывает на свойство, к которому будет применяться данный сеттер. Имеет следующий синтаксис:

    Property="Тип_элемента.Свойство_элемента"

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

    <Setter Property="Button.FontFamily" Value="Arial" />
  • Value: устанавливает значение для свойства из Property

Если значение свойства представляет сложный объект, то мы можем его вынести в отдельный элемент:

<Style x:Key="ButtonStyle" TargetType="Button">
    <Setter Property="Control.Background">
        <Setter.Value>
            <LinearGradientBrush StartPoint="0.5, 0" EndPoint="0.5, 1">
                <LinearGradientBrush.GradientStops>
                    <GradientStop Color="White" Offset="0" />
                    <GradientStop Color="Black" Offset="1" />
                </LinearGradientBrush.GradientStops>
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="Control.FontFamily" Value="Verdana" />
    <Setter Property="Control.Foreground" Value="White" />
    <Setter Property="Control.Margin" Value="10" />
</Style>

TargetType

Hам необязательно прописывать для всех кнопок стиль. Достаточно с помощью свойства TargetType задать тип элементов. В этом случае ключ ресурса в стиле не указывается, а сам стиль будет автоматически применяться ко всем кнопкам в окне:

<Page
    x:Class="BindingApp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:BindingApp"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.Resources>
        <Style TargetType="Button" >
            <Setter Property="Control.FontFamily" Value="Verdana" />
            <Setter Property="Control.Background" Value="#34495e" />
            <Setter Property="Control.Foreground" Value="#ecf0f1" />
            <Setter Property="Control.Margin" Value="10" />
        </Style>
    </Page.Resources>
    <StackPanel x:Name="buttonsStack" >
        <Button x:Name="button1" Content="Кнопка 1"  />
        <Button x:Name="button2" Content="Кнопка 2" />
    </StackPanel>
</Page>

Также если используем свойство TargetType без ключа ресурса, то у атрибута Property уже необязательно указывать тип, то есть Property="Control.FontFamily". И в данном случае тип можно просто опустить: Property="FontFamily"

Если же необходимо, чтобы к какой-то кнопке не применялся автоматический стиль, то ее стилю присваивают значение null:

<Button x:Name="button2" Content="Кнопка 2" Style="{x:Null}" />

Наследование стилей и свойство BasedOn

С помощью свойства BasedOn мы можем наследовать стили:

<Page.Resources>
    <Style x:Key="ButtonParentStyle" TargetType="Button">
        <Setter Property="Button.Background" Value="Black" />
        <Setter Property="Button.Foreground" Value="White" />
        <Setter Property="Button.FontFamily" Value="Arial" />
    </Style>
    <Style x:Key="ButtonChildStyle" TargetType="Button" BasedOn="{StaticResource ButtonParentStyle}">
        <Setter Property="Button.BorderBrush" Value="Red" />
        <Setter Property="Button.FontFamily" Value="Verdana" />
    </Style>
</Page.Resources>

Cвойство BasedOn в качестве значения принимает ссылку на уже существующий стиль и объединяет его функционал со своим собственным.

Если в дочернем стиле есть сеттеры для свойств, которые также используются в родительском стиле, как в данном случае сеттер для свойства Button.FontFamily, то дочерний стиль переопределяет родительский стиль.

Установка стилей в коде C#

В C# стили представляют объект Windows.UI.Xaml.Style. Используя его, мы можем добавлять сеттеры и устанавливать стиль для нужных элементов:

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI;

namespace BindingApp
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();

            Style buttonStyle = new Style();
            buttonStyle.Setters.Add(new Setter { Property = Control.FontFamilyProperty, Value = new FontFamily("Verdana") });
            buttonStyle.Setters.Add(new Setter { Property = Control.MarginProperty, Value = new Thickness(10) });
            buttonStyle.Setters.Add(new Setter { Property = Control.BorderBrushProperty, Value = new SolidColorBrush(Colors.Gray) });
            buttonStyle.Setters.Add(new Setter { Property = Control.BackgroundProperty, Value = new SolidColorBrush(Colors.Black) });
            buttonStyle.Setters.Add(new Setter { Property = Control.ForegroundProperty, Value = new SolidColorBrush(Colors.White) });
            buttonStyle.TargetType = typeof(Button);

            button1.Style = buttonStyle;
            button2.Style = buttonStyle;
        }
        
    }
}

Чтобы создать сеттер, нужно использовать свойство зависимостей, например, Property = Control.FontFamilyProperty. Причем для свойства Value у сеттера должен быть установлен объект именно того типа, которое хранится в этом свойстве зависимости. Так, свойство зависимости MarginProperty представляет объект Thickness, поэтому определение сеттера выглядит следующим образом:

new Setter { Property = Control.MarginProperty, Value = new Thickness(10) }
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850