1. tera1707

    Posted

    tera1707
Changes in title
+[WPF] Buttonをマウスクリック/タッチしたときのイベントの流れ(親子関係あり)
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,150 @@
+**全体もくじ**
+⇒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
+
+# やりたいこと
+
+ボタン単品を指でタッチしたりクリックしたときのイベントの流れを[以前の記事](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の解説をしっかり読んで、かつ使う前にどういう動作、伝わり方をするか実験してから使った方がよさそう。