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

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

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

# やりたいこと

ボタン単品を指でタッチしたりクリックしたときのイベントの流れを[以前の記事](https://qiita.com/tera1707/items/53d17c2534d75bf36853)で試してみたが、今度は親子関係のあるコントロール、例えばGridの中に入ってるButtonを押したときにどういうイベントの流れになるのかを今一度確認したい。

# 実験プログラム

## コード

[以前の記事で使ったもの](https://qiita.com/tera1707/items/53d17c2534d75bf36853#%E3%82%B3%E3%83%BC%E3%83%89)をほぼ流用する。ただし、Gridの中にButtonを入れてやる。

``` 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">

            <Button Margin="50" Content="ボタン"
                Grid.Row="0"
                Click="Button_Click"
                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>

```

## 画面見た目

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/1c19ec8a-8392-71c5-5fa4-c0a80ea61280.png)


# 結果

## Gridの中のButtonを指で押したとき

### 出力

下記のような出力になった。

```
MainGrid_PreviewStylusDown
Button_PreviewStylusDown
Button_StylusDown
MainGrid_StylusDown
MainGrid_PreviewTouchDown
Button_PreviewTouchDown
Button_TouchDown
MainGrid_TouchDown
MainGrid_PreviewMouseLeftButtonDown
MainGrid_PreviewMouseDown
Button_PreviewMouseLeftButtonDown
Button_PreviewMouseDown
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_Click
```

図で書くと、下記のようになった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/08e0cff1-68f6-87a7-524c-f5f8147d5993.png)



### クセが強いと思った部分①

[単品のButtonを押したときにもクセが強いと思った](https://qiita.com/tera1707/items/53d17c2534d75bf36853#%E3%82%AF%E3%82%BB%E3%81%8C%E3%81%82%E3%82%8B%E3%81%AA%E3%81%A8%E6%80%9D%E3%81%86%E7%82%B9%E3%81%9D%E3%81%AE-1)点だが、
`<Button>`では、`PreviewMouseLeftButtonDown`に対応する`MouseLeftButtonDown`など、マウスを押したとき系イベントのトンネリングイベントは来るが、バブリングイベントは来ない。

### クセが強いと思った部分②

①にも関連するが、`PreviewMouseLeftButtonDown`と`PreviewMouseDown`は、

- `PreviewMouseLeftButtonDown`が親⇒子に行ってから`PreviewMouseDown`が親⇒子に行くのではなく、
- `PreviewMouseLeftButtonDown`が親だけに行ったら`PreviewMouseDown`が親だけに行き、`PreviewMouseLeftButtonDown`が子だけに行って`PreviewMouseDown`が子だけに行く

という流れになる。
`StylusDown`や`TouchDown`は何となくイメージ通りだが、Mouse系はお互いのイベントが関係していて、出る順番が決まっているっぽい。


## Gridの中のButtonをマウスでクリックしたとき

上の結果から、Stylus系イベントとTouch系イベントをまるっと抜いたイベントが来る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/e0f8d1b2-832d-3fde-0ec8-0d262a64c76c.png)


# 考察

すべてのイベントが、一貫したルール(トンネリングイベントが親⇒子の方向に伝わり、次にバブリングイベントが子⇒親の方向に伝わる)のではなく、イベント個々で伝わり方に色々個性があるっぽい。
そのあたりは、個々のイベントのMSの解説をしっかり読んで、かつ使う前にどういう動作、伝わり方をするか実験してから使った方がよさそう。


# 参考

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