WPFのスタイルは、主にSetterとTriggerで構成されます。Setterはコントロールの静的な外観を設定し、Triggerはその動作を制御します。
Setterの概要
Setterでは、Property属性を使用してどのプロパティに値を設定するか指定し、Value属性で具体的な値を与えます。
<Window x:Class="WpfApp.StyleExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="StyleExample" Height="300" Width="400">
<Window.Resources>
<Style TargetType="Label">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="FontSize" Value="18"/>
</Style>
</Window.Resources>
<StackPanel Margin="10">
<Label Content="こんにちは WPF!" />
<Label Content="スタイルの例です。" />
<Label Content="Time 2023-10-01!" Style="{x:Null}" />
</StackPanel>
</Window>
ControlTemplateを設定したい場合は、SetterのPropertyをTemplateに設定し、対応するControlTemplateオブジェクトを提供します。
Triggerの基本
Triggerは、条件が満たされたときに特定の動作を実行します。イベントやデータ変更に基づいてトリガーすることができます。
単純なTrigger
以下はチェックボックスが選択された際にフォントサイズと色を変更する例です。
<Window x:Class="WpfApp.TriggerExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TriggerExample" Height="200" Width="300">
<Window.Resources>
<Style TargetType="CheckBox">
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="FontSize" Value="22"/>
<Setter Property="Foreground" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel Margin="10">
<CheckBox Content="A" />
<CheckBox Content="B" />
<CheckBox Content="C" />
<CheckBox Content="D" />
</StackPanel>
</Window>
MultiTriggerの使用
複数の条件が同時に満たされたときにトリガーを発動させることができます。
<Style TargetType="CheckBox">
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True"/>
<Condition Property="Content" Value="B"/>
</MultiTrigger.Conditions>
<Setter Property="FontSize" Value="24"/>
<Setter Property="Foreground" Value="Purple"/>
</MultiTrigger>
</Style.Triggers>
</Style>
DataTriggerの適用
データバインディングを使用してトリガーを設定できます。以下はテキストボックスの文字列長が7未満の場合に境界線を赤くする例です。
<Window x:Class="WpfApp.DataTriggerExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp"
Title="DataTriggerExample" Height="200" Width="400">
<Window.Resources>
<local:StringLengthConverter x:Key="lengthConverter"/>
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text.Length, Converter={StaticResource lengthConverter}}" Value="false">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="2"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel Margin="10">
<TextBox Height="30" />
<TextBox Height="30" />
</StackPanel>
</Window>
public class StringLengthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int length = (int)value;
return length >= 7 ? true : false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
MultiDataTriggerの活用
複数のデータソースに対して条件を設定し、すべてが満たされた場合にトリガーを発動させます。
<Style TargetType="ListBoxItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}" Width="50"/>
<TextBlock Text="{Binding Name}" Width="100"/>
<TextBlock Text="{Binding Skill}" Width="80"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Id}" Value="2"/>
<Condition Binding="{Binding Name}" Value="Darren"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="Yellow"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
EventTriggerによるアニメーション
EventTriggerは、特定のイベントが発生した際にアニメーションを実行します。
<Window x:Class="WpfApp.EventTriggerExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="EventTriggerExample" Height="300" Width="400">
<Window.Resources>
<Style TargetType="Button">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation To="120" Duration="0:0:0.3" Storyboard.TargetProperty="Width"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation To="80" Duration="0:0:0.3" Storyboard.TargetProperty="Width"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Button Content="クリック" Width="80" Height="40"/>
</Grid>
</Window>
Triggerはスタイルだけでなく、テンプレート内でも使用可能です。