Стили и триггеры WPF C#

Стиль – это коллекция значений свойств, которые могут быть применены к элементу. Система стилей WPF играет ту же роль, что и CSS в HTML.

Ресурсы


Ресурсы предоставляют то же решение, что и стили, но они являются
громоздкими и не удобными. Так будет выглядеть объявление ресурса:

 <!--Ресурсы окна -->
    <Window.Resources>
        <FontFamily x:Key="ButtonFontFamily">Times New Roman</FontFamily>
        <sys:Double x:Key="ButtonFontSize">18</sys:Double>
        <FontWeight x:Key="ButtonFontWeight">Bold</FontWeight>
    </Window.Resources>

    <StackPanel Margin="5">

        <Button Padding="5" Margin="5"
            FontFamily="{StaticResource ButtonFontFamily}"
            FontWeight="{StaticResource ButtonFontWeight}"
            FontSize="{StaticResource ButtonFontSize}">
            Кнопка с настройками
        </Button>

        <TextBlock Margin="5">Обычный контент.</TextBlock>

        <Button Padding="5" Margin="5">Обычная кнопка</Button>

        <TextBlock Margin="5">Еще обычный контент.</TextBlock>

        <Button Padding="5" Margin="5"
            FontFamily="{StaticResource ButtonFontFamily}"
            FontWeight="{StaticResource ButtonFontWeight}"
            FontSize="{StaticResource ButtonFontSize}">
            Кнопка с настройками
        </Button>

    </StackPanel>

 

Недостатки


• Нет никакого четкого признака, что все три ресурса связаны между собой. Это делает приложение менее удобным для дальнейшего сопровождения.
• Код разметки для применения такого подхода будет хранить слишком большое количество описаний.

Создание стиля

Определения объекта стиля в ресурсах окна:

 <Window.Resources>
        <!--Объявление стиля c ключом MyButtonStyle-->
        <Style x:Key="MyButtonStyle">
            <Setter Property="Button.FontFamily" Value="Times New Roman" />
            <Setter Property="Button.FontSize" Value="18" />
            <Setter Property="Button.FontWeight" Value="Bold" />
        </Style>
    </Window.Resources>

    <StackPanel Margin="5">
        <Button Padding="5" Margin="5" FontSize="24"
            Style="{StaticResource MyButtonStyle}">
            Кнопка со стилем
        </Button>

        <TextBlock Margin="5">Статический контент</TextBlock>

        <Button Padding="5" Margin="5">Обычная кнопка</Button>

        <TextBlock Margin="5">Статический контент</TextBlock>

        <!--Каждый элемент управления WPF может использовать один стиль.
        (Свойство Style определено в базовом классе FrameworlElement)-->
        <Button Padding="5" Margin="5"
            Style="{StaticResource MyButtonStyle}">
            Кнопка со стилем
        </Button>
    </StackPanel>

Ключевые свойства стиля

Setters – коллекция объектов, которые автоматически устанавливают значение свойств элементов управления.
Triggers – коллекция объектов, которые позволяют автоматически изменять параметры стиля.
BasedOn – для создания стиля, который наследует другой стиль и переопределят его значения.
TargetType – указывает тип элементов на которые действует стиль.

Триггеры Triggers

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

Основные типы триггеров

Trigger – Самый простой триггер. Следит за изменением значения свойства.
MultiTrigger– Похож на первый но срабатывает при выполнении множества условий.
DataTriger – Срабатывает при изменении в связанных с ним данных.
MultiDataTrigger – множество триггеров данных.
EventTrigger– При возникновении события он применяет соответствующую анимацию.

Пример триггера:

<Window.Resources>
        <Style x:Key="BigFontButtonStyle">
            
            <Style.Setters>
                <Setter Property="Control.FontFamily" Value="Times New Roman" />
                <Setter Property="Control.FontSize" Value="18" />
            </Style.Setters>
            
            <!--Триггеры-->
            <Style.Triggers>
                
                <!--Если элемент в фокусе значение Foreground устанавливается как DarkRed-->
                <Trigger Property="Control.IsFocused" Value="True">
                    <Setter Property="Control.Foreground" Value="Yellow" />
                </Trigger>

                <!--Если курсор находится над элементом, устанавливаются свойства Foreground и FontWeight-->
                <Trigger Property="Control.IsMouseOver" Value="True">
                    <Setter Property="Control.Foreground" Value="Green" />
                    <Setter Property="Control.FontWeight" Value="Bold" />
                </Trigger>

                <!--Если курсор находится над элементом, устанавливаются свойства Foreground и FontWeight-->
                <Trigger Property="Button.IsPressed" Value="True">
                    <Setter Property="Control.Foreground" Value="Red" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>

    <StackPanel Margin="5">
        
        <Button Padding="5" 
                Margin="5"
                Style="{StaticResource BigFontButtonStyle}">Кнопка со стилями и триггерами
        </Button>
        
        <TextBlock Margin="5">Обычный контент.</TextBlock>
        
        <Button Padding="5" 
                Margin="5">
            Обычная кнопка
        </Button>

        <TextBlock Margin="5">Обычный контент.</TextBlock>
        <Button Padding="5"
                Margin="5"
                Style="{StaticResource BigFontButtonStyle}">
            Кнопка со стилями и триггерами
        </Button>
    </StackPanel>

Пример мульти триггера. MultiTrigger

   <Window.Resources>
        <Style x:Key="MyButtonStyle">
            <Style.Triggers>
                <MultiTrigger>
                    
                    <!--Список условий-->
                    <MultiTrigger.Conditions>
                        <Condition Property="Control.IsFocused" Value="True"></Condition>
                        <Condition Property="Control.IsMouseOver" Value="True"></Condition>
                    </MultiTrigger.Conditions>
                    
                    <!--Список изменений, которые вступят в силу, если все условия выполнятся-->
                    <MultiTrigger.Setters>
                        <Setter Property="Control.Foreground" Value="DarkBlue"></Setter>
                        <Setter Property="Control.FontSize" Value="20"></Setter>
                    </MultiTrigger.Setters>
                    
                </MultiTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    
    <StackPanel>
        
        <Button Name="Button1" Style="{StaticResource MyButtonStyle}" Margin="20">
            A Button
        </Button>
        <Button Name="Button2" Style="{StaticResource MyButtonStyle}" Margin="20">
            A Button
        </Button>
        
    </StackPanel>

 

Пример MultiDataTrigger

<Window.Resources>
        <!--В качестве ресурса используем класс-коллекцию из code behind-->
        <c:Countries x:Key="PlacesData"/>

        <!--Стиль для ListBoxItem-->
        <Style TargetType="ListBoxItem">
            <Style.Triggers>
                <!--Если значение свойства ShortName объекта с этим стилем будет равно USA - текст станет красного цвета-->
                <DataTrigger Binding="{Binding Path=ShortName}" Value="USA">
                    <Setter Property="Foreground" Value="Red" />
                </DataTrigger>
                <!--Если значение свойства ShortName и Name будут равны значениям указаным в Value
                то для элемента будет пременен стиль указаный в тэге Setter-->
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=Name}" Value="Ukraine" />
                        <Condition Binding="{Binding Path=ShortName}" Value="UA" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="Background" Value="Cyan" />
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>

    <StackPanel>
        <TextBlock FontSize="18"
                   Margin="5"
                   FontWeight="Bold"
                   HorizontalAlignment="Center">
            Пример работы с DataTrigger
        </TextBlock>

        <!--ListBox, который использует привязку.-->
        <ListBox Width="180" 
                 HorizontalAlignment="Center" 
                 Background="Honeydew"
                 ItemsSource="{Binding Source={StaticResource PlacesData}}"/>
    </StackPanel>

 

Пример EventTrigger

<Window.Resources>

        <Style x:Key="BigFontButton">
            <!--Стили-->
            <Style.Setters>
                <Setter Property="Control.FontFamily" Value="Times New Roman" />
                <Setter Property="Control.FontSize" Value="18" />
                <Setter Property="Control.FontWeight" Value="Bold" />
            </Style.Setters>
            <!--Триггеры
            Обычные тригеры ожидают изменения свойств
            EventTrigger - ожидает определенного события-->
            <Style.Triggers>
                <!--Действие на событие MouseEnter-->
                <EventTrigger RoutedEvent="Mouse.MouseEnter">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation
                                    Duration="0:0:0.2"
                                    Storyboard.TargetProperty="FontSize"
                                    To="22"  />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
                <!--Действие на событие MouseLeave-->
                <EventTrigger RoutedEvent="Mouse.MouseLeave">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation
                                    Duration="0:0:1"
                                    Storyboard.TargetProperty="FontSize" To="18"  />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>

            </Style.Triggers>
        </Style>

    </Window.Resources>

    <StackPanel Margin="5">

        <Button Padding="5"
                Margin="5"
                Style="{StaticResource BigFontButton}">
            Кнопка со стилем и триггерами
        </Button>

        <TextBlock Margin="5">Обычный контент.</TextBlock>

        <Button Padding="5" Margin="5">
            Обычная кнопка
        </Button>
        <TextBlock Margin="5">Еще один обычный контент.</TextBlock>
        <Button Padding="5" 
                Margin="5"
                Style="{StaticResource BigFontButton}">
            Кнопка со стилем и триггерами
        </Button>
    </StackPanel>

 

Обновлено: 28.02.2021 — 15:51

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.