Стиль – это коллекция значений свойств, которые могут быть применены к элементу. Система стилей WPF играет ту же роль, что и CSS в HTML.
Ресурсы
Ресурсы предоставляют то же решение, что и стили, но они являются
громоздкими и не удобными. Так будет выглядеть объявление ресурса:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<!--Ресурсы окна --> <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> |
Недостатки
• Нет никакого четкого признака, что все три ресурса связаны между собой. Это делает приложение менее удобным для дальнейшего сопровождения.
• Код разметки для применения такого подхода будет хранить слишком большое количество описаний.
Создание стиля
Определения объекта стиля в ресурсах окна:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<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– При возникновении события он применяет соответствующую анимацию.
Пример триггера:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
<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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
<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> |