0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[WPF]GridのIsMouseOverを使うときは、背景色を設定しないとうまく動かない

Posted at

はじめに

本文書は筆者がWPFで開発する中でGridのIsMouseOverを使おうとしたときの困りごとについてまとめます。

困りごとの例

Gridに3つボタンを並べて、1つのボタンはGridにマウスオーバーされたときに表示するようにしたい状況を考えます。
そのために、WPFプロジェクトをVisualStudioで作ると生成されるMainWindow.xamlを以下のように編集しました。

<Window x:Class="MouseOverSample.MainWindow"
        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"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.Resources>
        <Style x:Key="DisplayedOnMouseOverButtonStyle" TargetType="{x:Type Button}">
            <Setter Property="Visibility" Value="Collapsed"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorLevel=1, AncestorType={x:Type Grid}}, Path=IsMouseOver}" Value="True">
                    <Setter Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <!-- 以下2つのボタンは常に表示される -->
        <Button Grid.Column="0" 
                Height="20" Width="40"
                Content="ボタン1"/>
        <Button Grid.Column="1" 
                Height="20" Width="40"
                Content="ボタン2"/>
        <!-- 以下のボタンはグリッドがマウスオーバーされたときのみ表示する -->
        <Button Grid.Column="2" 
                Height="20" Width="40"
                Style="{StaticResource DisplayedOnMouseOverButtonStyle}"
                Content="ボタン3"/>
    </Grid>
</Window>

GridのColumnを3つに分けて、それぞれのColumnにボタンを1つずつ配置しています。
ただ、3つ目のボタンだけはスタイルを指定しています。指定しているスタイルは、ボタンが配置されているGridのIsMouseOverがTrueの時のみ表示されるといったものです。以下がスタイルの部分です。

<Style x:Key="DisplayedOnMouseOverButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="Visibility" Value="Collapsed"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorLevel=1, AncestorType={x:Type Grid}}, Path=IsMouseOver}" Value="True">
            <Setter Property="Visibility" Value="Visible"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

上記のMainWindow.xamlをビルドして、実行してみると以下のような極めて簡素なUIができます。

image.png

そして、肝心の3つ目のボタンですが、想定通りに動作しません。
具体的には、以下のように[ボタン1]と[ボタン2]にマウスオーバーした時には表示されますが、そのほかの何もコントロールが配置されていない部分のGrid領域にマウスオーバーしても表示されないです。

想定外動作.gif

困りごとの解決法

解決法としてはGridに任意の背景色を設定してあげることです。
そうすることでGrid内でコントロールが配置されていない空の領域にマウスオーバーした際にもIsMouseOverがTrueを返すようになり、想定通りに動作するようになります。
前章で記載したMainWindow.xamlにおいては、以下のようにGridに対して、背景色を設定します。なお、見た目を変えないようにTransparent(透明)を設定しています。

<Window x:Class="MouseOverSample.MainWindow"
        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"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.Resources>
        ...
    </Window.Resources>

    <!-- Gridに背景色を設定 -->
    <Grid Background="Transparent">
        ...
    </Grid>
</Window>

上記の変更で想定通りに動作するようになります。
以下が動作イメージです。

想定動作.gif

まとめ

筆者が困ったGridのIsMouseOverを使うときの注意点をまとめました。
なお、Grid以外にもStackPanelやWrapPanelであっても同じように背景色を設定してあげないと想定外の動作をするので、覚えておきたいですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?