[WPF] Gridをマウスクリック/タッチしたときのイベントの流れ(親子関係あり)


全体もくじ
https://qiita.com/tera1707/items/4fda73d86eded283ec4f

イベント関連のもくじ
https://qiita.com/tera1707/items/4fda73d86eded283ec4f#%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E9%96%A2%E9%80%A3wpfxaml

やりたいこと

以前の記事で、Gridの中にButtonを配置して、イベントの流れがどうなるか見てみた。
そのときは、Buttonの特性(ButtonBaseの特性)?により、Mouse系のバブルイベントは来ない、ということが分かった。

では、Buttonではないコントロールを重ねた(親子にした)場合は、どのようなイベントの流れになるのか?見てみる。

やったこと

すべてのコントロールの親子の組み合わせはやってられないので、今回はGridの中にGridを入れて、実験した。

実験プログラム

基本は、以前の記事で作成したものを改造して使う。
下記のように、xamlのみ改造した。
(元々ButtonだったところをGridに直したのだが、全部のイベントハンドラの名前を変えるのが面倒なので、そのままにしとく)

コード

MainWindow.xaml
<Window x:Class="WpfApp64.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"
        xmlns:local="clr-namespace:WpfApp64"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="0*"/>
        </Grid.RowDefinitions>

        <Grid x:Name="MainGrid"
              Background="#66FF0000"
              Grid.Row="0"
              Margin="50"
              IsManipulationEnabled="False" 
              ManipulationStarting="MainGrid_ManipulationStarting" 
              ManipulationDelta="MainGrid_ManipulationDelta"
              ManipulationCompleted="MainGrid_ManipulationCompleted"

              PreviewMouseDown=             "MainGrid_PreviewMouseDown"             MouseDown="MainGrid_MouseDown"
              PreviewMouseUp=               "MainGrid_PreviewMouseUp"               MouseUp="MainGrid_MouseUp"
              PreviewTouchDown=             "MainGrid_PreviewTouchDown"             TouchDown="MainGrid_TouchDown"
              PreviewTouchUp=               "MainGrid_PreviewTouchUp"               TouchUp="MainGrid_TouchUp"
              PreviewStylusDown=            "MainGrid_PreviewStylusDown"            StylusDown="MainGrid_StylusDown"
              PreviewStylusUp=              "MainGrid_PreviewStylusUp"              StylusUp="MainGrid_StylusUp"
              PreviewMouseLeftButtonDown=   "MainGrid_PreviewMouseLeftButtonDown"   MouseLeftButtonDown="MainGrid_MouseLeftButtonDown"
              PreviewMouseLeftButtonUp=     "MainGrid_PreviewMouseLeftButtonUp"     MouseLeftButtonUp="MainGrid_MouseLeftButtonUp"
              PreviewMouseRightButtonDown=  "MainGrid_PreviewMouseRightButtonDown"  MouseRightButtonDown="MainGrid_MouseRightButtonDown"
              PreviewMouseRightButtonUp=    "MainGrid_PreviewMouseRightButtonUp"    MouseRightButtonUp="MainGrid_MouseRightButtonUp">

            <Grid Margin="50" Background="Yellow"
                PreviewMouseDown="Button_PreviewMouseDown"                          MouseDown="Button_MouseDown"
                PreviewMouseUp="Button_PreviewMouseUp"                              MouseUp="Button_MouseUp"
                PreviewTouchDown="Button_PreviewTouchDown"                          TouchDown="Button_TouchDown"
                PreviewTouchUp="Button_PreviewTouchUp"                              TouchUp="Button_TouchUp"
                PreviewStylusDown="Button_PreviewStylusDown"                        StylusDown="Button_StylusDown"
                PreviewStylusUp="Button_PreviewStylusUp"                            StylusUp="Button_StylusUp"
                PreviewMouseLeftButtonDown="Button_PreviewMouseLeftButtonDown"      MouseLeftButtonDown="Button_MouseLeftButtonDown"
                PreviewMouseLeftButtonUp="Button_PreviewMouseLeftButtonUp"          MouseLeftButtonUp="Button_MouseLeftButtonUp"
                PreviewMouseRightButtonDown="Button_PreviewMouseRightButtonDown"    MouseRightButtonDown="Button_MouseRightButtonDown"
                PreviewMouseRightButtonUp="Button_PreviewMouseRightButtonUp"        MouseRightButtonUp="Button_MouseRightButtonUp"
            />
        </Grid>

        <Button Name="KirikaeBtn" 
                Width="150" Height="40" 
                HorizontalAlignment="Left" VerticalAlignment="Top" 
                Content="false"
                Click="IsManipulationEnabledChange"/>
    </Grid>
</Window>

画面

赤いところが親のGrid、黄色いところが子のGrid。

結果

子のGridを手でタッチしたとき

結果、下記のような出力となった。
※「Button_〇〇」となっているイベントが、子のGridのイベント。

MainGrid_PreviewStylusDown
Button_PreviewStylusDown
Button_StylusDown
MainGrid_StylusDown
MainGrid_PreviewTouchDown
Button_PreviewTouchDown
Button_TouchDown
MainGrid_TouchDown
MainGrid_PreviewMouseLeftButtonDown
MainGrid_PreviewMouseDown
Button_PreviewMouseLeftButtonDown
Button_PreviewMouseDown
Button_MouseLeftButtonDown
Button_MouseDown
MainGrid_MouseLeftButtonDown
MainGrid_MouseDown
MainGrid_PreviewStylusUp
Button_PreviewStylusUp
Button_StylusUp
MainGrid_StylusUp
MainGrid_PreviewTouchUp
Button_PreviewTouchUp
Button_TouchUp
MainGrid_TouchUp
MainGrid_PreviewMouseLeftButtonUp
MainGrid_PreviewMouseUp
Button_PreviewMouseLeftButtonUp
Button_PreviewMouseUp
Button_MouseLeftButtonUp
Button_MouseUp
MainGrid_MouseLeftButtonUp
MainGrid_MouseUp

絵で描くとこういう流れ。

Buttonをタッチしたときと比べて

Buttonをタッチしたときとは、下記のような違いがあった。

  • 当たり前だが、Clickイベントがない。
  • 子Buttonを押したときには来なかったMouseLeftButtonDownMouseDownのバブリングイベントが来る。(Upも同様)
  • StylusとかTouch系のイベントは変化なし。

参考

MSかずきさん イベント解説
https://qiita.com/okazuki/items/43e98bf7107c3e710177