HTML + CSS だとマウスオーバーで色が変わるハイパーリンクはスクリプトを使わずとも CSS だけで書けるわけですが、それと同様のことを WPF でやる話。

ちなみに HTML + CSS の場合は以下の通り。

a:link  { color: blue; }
a:hover { color: red; }

他にも a:visited とか a:active とかあるだろうけど気にしない。

さて本題。

コントロール自身のプロパティを元に他のプロパティ等を変更するには Trigger というものを使います。ただし、Button クラスの(より正確には FrameworkElement クラスの) Triggers プロパティに指定できるのは EventTrigger だけなので、スタイルやテンプレートを経由して設定する必要があります(EventTrigger でも書けないことはないけど Trigger を使った方が簡潔)。結果としてこんな感じ。

<Window x:Class="MouseOverButtonTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="128" Width="192">
    <StackPanel VerticalAlignment="Center">
        <Button Content="Button">
            <Button.Style>
                <Style TargetType="Button">
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Foreground" Value="Red"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </StackPanel>
</Window>

マウスオーバーで色が変わるボタン

なお、マウスオーバーしていない時の色を別途指定したい場合は、スタイルの中に Setter を書く必要があります。Button 要素の属性として書いてしまうと、スタイルに書いたトリガーで起動される当該プロパティに対する Setter は効かなくなります。

<Window x:Class="MouseOverButtonTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="128" Width="192">
    <StackPanel VerticalAlignment="Center">
        <!-- こっちは意図した結果にならない -->
        <Button Content="Bad!!" Foreground="Blue">
            <Button.Style>
                <Style TargetType="Button">
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Foreground" Value="Red"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
        
        <!-- こっちはOK -->
        <Button Content="Good!!">
            <Button.Style>
                <Style TargetType="Button">
                    <Setter Property="Foreground" Value="Blue"/>
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Foreground" Value="Red"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </StackPanel>
</Window>

もちろん、依存関係プロパティであれば何でも変更可能なわけで、変更するプロパティとして Opacity を指定すると、平常時は透明でマウスオーバーすると見えるようになるボタンとか作れます(私が元々これを調べているときにやりたかったのはこれ)。ただこれ、マウスを使わずキーボードだけでボタンを操作する場合は透明なままになってしまうので、もうちょっと考えないといけない気がします。

Trackback

no comment untill now

Add your comment now