VB のたまご

作成日: 2017/03/07, 更新日: 2017/03/07



Trigger

  •  以前 Style の説明をしましたが、スタイル設定の中には、無条件で設定するのではなく、ある状態の場合だけスタイル設定を効かせたいことがあります。 例えば、ボタンに対して、マウスオーバーしている最中だけ強調したいなどです。 Trigger(トリガー)は、こういう時に使う仕組みになります。 とりあえずどういう風に動くのか見てみましょう。 以下サンプルです。「TriggerWindow1」という画面で作成していますが、「MainWindow」に書いても構いません。

  • スポンサーリンク


    <Window x:Class="TriggerWindow1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:w05_WpfSystem"
            mc:Ignorable="d"
            Title="TriggerWindow1" Height="300" Width="300">
       
        <StackPanel>
    
            <StackPanel.Resources>
                
                <Style TargetType="Button">
                    <Setter Property="Background" Value="Red" />
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="FontSize" Value="24" />
                            <Setter Property="FontStyle" Value="Italic" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
    
            </StackPanel.Resources>
    
            <Button Content="button1" />
    
        </StackPanel>
        
    </Window>
    

  •  実行したらマウスの上にカーソルを当ててみてください。button1 の文字列が大きくなって斜体になったと思います。 マウスカーソルを外すと元の設定に戻ります。

  •  トリガーの条件は複数割り当てることができます。以下サンプルです。

  • <Window x:Class="TriggerWindow2"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:w05_WpfSystem"
            mc:Ignorable="d"
            Title="TriggerWindow2" Height="300" Width="300">
    
        <StackPanel>
    
            <StackPanel.Resources>
    
                <Style TargetType="Button">
                    <Setter Property="Background" Value="Red" />
                    <Style.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsFocused" Value="True" />
                                <Condition Property="IsMouseOver" Value="True" />
                            </MultiTrigger.Conditions>
                            <Setter Property="FontSize" Value="24" />
                            <Setter Property="FontStyle" Value="Italic" />
                        </MultiTrigger>
                    </Style.Triggers>
                </Style>
    
            </StackPanel.Resources>
    
            <TextBox Text="textbox1" />
            <Button Content="button1" />
            <TextBox Text="textbox2" />
    
        </StackPanel>
    
    </Window>
    

  •  このサンプルでは、ボタンにフォーカスが当たっている、かつマウスオーバー時に限り、フォントサイズが24で斜体に変更します。 よって、ボタンをクリックした際か、タブキーでボタンにフォーカス移動してからマウスオーバーすると変更します。

  • スポンサーリンク


  •  トリガーには種類があり、プロパティを条件にする以外に、バインドしているデータクラスの値を条件にすることもできます。 以下サンプルです。

  • <Window x:Class="TriggerWindow3"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:w05_WpfSystem"
            mc:Ignorable="d"
            Title="TriggerWindow3" Height="300" Width="300"
            Loaded="Window_Loaded">
        
        <StackPanel>
    
            <StackPanel.Resources>
    
                <Style TargetType="Button">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=Name}" Value="taro">
                            <Setter Property="Foreground" Value="Red" />
                            <Setter Property="FontStyle" Value="Italic" />
                            <Setter Property="FontSize" Value="24" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
    
            </StackPanel.Resources>
    
            <Button Name="button1" Content="{Binding Name}" />
            <Button Name="button2" Content="{Binding Name}" />
            <Button Name="button3" Content="{Binding Name}" />
    
        </StackPanel>
        
    </Window>
    

    Public Class TriggerWindow3
    
        Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
    
            Me.button1.DataContext = New Person With {.Name = "taro", .Age = 23, .IsMan = True}
            Me.button2.DataContext = New Person With {.Name = "jiro", .Age = 27, .IsMan = True}
            Me.button3.DataContext = New Person With {.Name = "hanako", .Age = 33, .IsMan = False}
    
        End Sub
    
        Private Class Person
    
            Public Property Name As String = String.Empty
            Public Property Age As Integer = -1
            Public Property IsMan As Boolean = False
    
            Public Overrides Function ToString() As String
    
                Dim gender = If(IsMan = True, "男", "女")
                Return "{" & Name & ", " & Age.ToString() & ", " & gender & "}"
    
            End Function
    
        End Class
    
    End Class
    

  •  「バインド」に関しては、MVVM 編で説明するのでここでは簡単に流れだけ説明します。 最初はロードイベント内の処理からです。ボタンの DataContext プロパティにデータクラスのインスタンスをセットしています。 DataContext プロパティへバインドしたデータはコントロール内で表示されます。

  •  次に、Xaml に記述したボタンの定義です。3つボタンを定義していますが、それぞれ、ボタンの Content プロパティに「Binding している Name プロパティ」を表示させるようにセットしています。 最後にスタイル設定のトリガーです。 データトリガーを使って、バインドしているデータクラスの「Name」プロパティが「taro」という値だった場合、ボタンの文字列を赤文字で、斜体で、サイズを24に変更するようにセットしています。 結果、実行すると1つ目のボタンが変化しましたね。

  •  MultiTrigger があるように、DataTrigger にも複数条件を割り当てることができます。以下のサンプルです。

  • <Window x:Class="TriggerWindow4"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:w05_WpfSystem"
            mc:Ignorable="d"
            Title="TriggerWindow4" Height="300" Width="300"
            Loaded="Window_Loaded">
    
        <StackPanel>
    
            <StackPanel.Resources>
    
                <Style TargetType="Button">
                    <Style.Triggers>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding Path=Name}" Value="jiro" />
                                <Condition Binding="{Binding Path=Age}" Value="27" />
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Foreground" Value="Red" />
                            <Setter Property="FontStyle" Value="Italic" />
                            <Setter Property="FontSize" Value="24" />
                        </MultiDataTrigger>
                    </Style.Triggers>
                </Style>
    
            </StackPanel.Resources>
    
            <Button Name="button1" Content="{Binding Name}" />
            <Button Name="button2" Content="{Binding Name}" />
            <Button Name="button3" Content="{Binding Name}" />
    
        </StackPanel>
    
    </Window>
    

    Public Class TriggerWindow4
    
        Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
    
            Me.button1.DataContext = New Person With {.Name = "taro", .Age = 23, .IsMan = True}
            Me.button2.DataContext = New Person With {.Name = "jiro", .Age = 27, .IsMan = True}
            Me.button3.DataContext = New Person With {.Name = "hanako", .Age = 33, .IsMan = False}
    
        End Sub
    
        Private Class Person
    
            Public Property Name As String = String.Empty
            Public Property Age As Integer = -1
            Public Property IsMan As Boolean = False
    
            Public Overrides Function ToString() As String
    
                Dim gender = If(IsMan = True, "男", "女")
                Return "{" & Name & ", " & Age.ToString() & ", " & gender & "}"
    
            End Function
    
        End Class
    End Class
    

  •  簡単ですね。 最後に、イベント発生を条件にできる EventTrigger の紹介です。 イベントトリガ―はアニメーションをセットするので(アニメーションは難しいので)、ここではさらっといきます。

  • <Window x:Class="TriggerWindow5"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:w05_WpfSystem"
            mc:Ignorable="d"
            Title="TriggerWindow5" Height="300" Width="300">
        
        <Grid>
    
            <Grid.Resources>
                <Style TargetType="Button">
                    <Style.Triggers>
                        
                        <EventTrigger RoutedEvent="MouseEnter">
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation
                                        Storyboard.TargetProperty="Height"
                                        To="100"
                                        Duration="0:0:1" />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
    
                        <EventTrigger RoutedEvent="MouseLeave">
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation
                                        Storyboard.TargetProperty="Height"
                                        To="30"
                                        Duration="0:0:1" />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
    
                    </Style.Triggers>
                </Style>
            </Grid.Resources>
    
            <Button Content="button1" Width="100" Height="30" />
    
        </Grid>
        
    </Window>
    

  •  ボタン上にマウスオーバーされると高さが広がっていき、ボタンからマウスを話すと高さが縮んでいくサンプルです。 MouseEnter, MouseLeave イベントを利用しています。