WPFにおけるスタイルの基礎

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のPropertyTemplateに設定し、対応する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はスタイルだけでなく、テンプレート内でも使用可能です。

タグ: WPF Style Trigger

8月7日 06:33 投稿