This article has been localized into Russian by the community.
A special thanks goes out to user #70 for the Russian translation of this article: Ilya Degtyarev
Использование стилей WPF
В предыдущей главе (посвященной модели стилей в WPF) мы рассмотрели простой базовый пример локально определенного стиля, направленного на все элементы выбранного типа - TextBlock. Однако, стили могут быть определены в различных областях кода, в зависимости от того, где и как Вы хотите их использовать и можете распространить их использование только на элементы, на которые хотите. В текущей главе я покажу Вам различные варианты определения стилей WPF.
Локальное определение стиля элемента управления
Вы можете определить стиль непосредственно на самом элементе, как показано ниже:
<Window x:Class="WpfTutorialSamples.Styles.ControlSpecificStyleSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ControlSpecificStyleSample" Height="100" Width="300">
<Grid Margin="10">
<TextBlock Text="Style test">
<TextBlock.Style>
<Style>
<Setter Property="TextBlock.FontSize" Value="36" />
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
</Window>
В этом примере, введенный стиль, относится лишь к одному текстовому полю, так в чем же проблема? Ну, в данном случае, это не играет никакой роли. Я мог бы перенести этот код стиля для размера текста внутрь открывающего тега TextBlock. Позже, Вы заметите, что с помощью стилей можно не только определять свойства элемента. Например, триггеры стилей могли бы позволить сделать пример выше пригодным для реального приложения. Однако, большинство стилей следует определять в более высокой области.
Локальный стиль дочернего элемента
Использование тега Resources внутри элемента позволяет охватить дочерние элементы этого элемента и сам элемент. Пример похож на тот, что был в показан в предыдущей главе, вспомним как он выглядел:
<Window x:Class="WpfTutorialSamples.Styles.SimpleStyleSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SimpleStyleSample" Height="200" Width="250">
<StackPanel Margin="10">
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Gray" />
<Setter Property="FontSize" Value="24" />
</Style>
</StackPanel.Resources>
<TextBlock>Header 1</TextBlock>
<TextBlock>Header 2</TextBlock>
<TextBlock Foreground="Blue">Header 3</TextBlock>
</StackPanel>
</Window>
Это отличный вариант для большинства ситуаций использования локальных стилей. Например, это имеет смысл, когда Вы хотите придать нескольким элементам похожий внешний вид, без индивидуального подхода к каждому элементу.
Стили для Окна
Следующим шагом будет определение стилей контейнера с помощью его "ресурсов" (Window - это наш главный контейнер на странице). Это делается абсолютно так же, как было выше для контейнера StackPanel, но удобным может быть для определения стилей элементов определенного типа в рамках всего главного контейнера (которым может быть Window, UserControl и другие). Так же следует заметить, что это относится не только к локально определенным контейнерам в текущей области, что интересно. Вот, модифицированный пример:
<Window x:Class="WpfTutorialSamples.Styles.WindowWideStyleSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowWideStyleSample" Height="200" Width="300">
<Window.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Gray" />
<Setter Property="FontSize" Value="24" />
</Style>
</Window.Resources>
<StackPanel Margin="10">
<TextBlock>Header 1</TextBlock>
<TextBlock>Header 2</TextBlock>
<TextBlock Foreground="Blue">Header 3</TextBlock>
</StackPanel>
</Window>
Как Вы могли заметить, результат получился абсолютно таким же. Можно размещать элементы управления в любых местах Окна, и стиль будет к ним применяться.
Стили приложения
Если Вы хотите распространить стиль на весь код, все окна, то можете определить его для целого приложения. Это можно реализовать в файле App.xaml (который Visual Studio вероятно уже создала для Вас), точно так же, как и в примере для стилей Окна:
App.xaml
<Application x:Class="WpfTutorialSamples.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Styles/WindowWideStyleSample.xaml">
<Application.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Gray" />
<Setter Property="FontSize" Value="24" />
</Style>
</Application.Resources>
</Application>
Window
<Window x:Class="WpfTutorialSamples.Styles.WindowWideStyleSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ApplicationWideStyleSample" Height="200" Width="300">
<StackPanel Margin="10">
<TextBlock>Header 1</TextBlock>
<TextBlock>Header 2</TextBlock>
<TextBlock Foreground="Blue">Header 3</TextBlock>
</StackPanel>
</Window>
Явное использование стилей
На данный момент Вы изучили уже несколько методов применения стилей к элементам управления: начиная от локальных стилей, заканчивая стилями всего приложения, которые могут придать ему желаемый вид, но... Последний вариант направлен на элементы выбранного типа, и ВСЕ элементы этого типа, будут попадать под выбранный стиль. Однако, это можно обойти.
Используя свойство x:Key в стиле, Вы сообщаете WPF, что хотите использовать данный стиль исключительно в том случае, когда ссылаетесь на него с выбранного элемента. Давайте исследуем пример на эту тему:
<Window x:Class="WpfTutorialSamples.Styles.ExplicitStyleSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ExplicitStyleSample" Height="150" Width="300">
<Window.Resources>
<Style x:Key="HeaderStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="Gray" />
<Setter Property="FontSize" Value="24" />
</Style>
</Window.Resources>
<StackPanel Margin="10">
<TextBlock>Header 1</TextBlock>
<TextBlock Style="{StaticResource HeaderStyle}">Header 2</TextBlock>
<TextBlock>Header 3</TextBlock>
</StackPanel>
</Window>
Заметьте, что целевым типом в стиле является TextBlock, но этот стиль применяется только ко второму текстовому полю, тому, в котором я непосредственно сослался на стиль HeaderStyle, используя свойство Style. Такой механизм позволяет Вам определять стили для выбранных типов, но лишь для тех элементов, которые ссылаются на этот тип.
Вывод
Стили WPF позволяют Вам с легкостью переиспользовать определенный вид элемента управления для всех элементов в приложении. А используя свойствйо x:Key, Вы решаете к каким именно элементам этот стиль будет относится: либо к выбранным с помощью селектора x:Key, либо ко всем в приложении.