WPF内のListboxにボタンを配置しタッチ操作する

move.jpg

WPFで、Listboxを用い、その中にボタンを配置した時のタッチ操作です。

どうも操作感がイマイチで、Clickイベントが発生する場合と発生しない場合があります。タッチの仕方によって、Listboxの行が選択されたようになります。

こちらに質問したら、親切に教えていただけました。ほんと助かります。
https://social.msdn.microsoft.com/Forums/ja-JP/eec04319-4e9c-43b8-b0fd-35e00515de66/listbox-?forum=wpfja&prof=required

Listboxの上でタッチする際に、指が少しでも動いてしまうと、スワイプしたような状態になりClickイベントが発生せず、TouchUpとかその他のイベントが発生して、行選択状態になるようです。教えていただいたコードとしては、

https://msdn.microsoft.com/ja-jp/library/system.windows.input.stylus.ispressandholdenabled(v=vs.110).aspx
プレス アンド ホールドは、マウスの右クリックにマップされます。Windows Vista では、ユーザーがタブレット ペンを押したままにする可能性があり、右クリックをシミュレートする必要のない要素上では、この動作を無効にできます。

http://www.atmarkit.co.jp/ait/articles/0411/19/news111.html
「e」のHandledプロパティは、イベントを処理したかどうかを設定するためのもの
HandledプロパティにTrueを設定している。これにより、コントロール側のKeyDownイベント・ハンドラは呼び出されなくなる

https://msdn.microsoft.com/ja-jp/library/ms754010(v=vs.110).aspx
ユーザーがその要素内で指を移動すると、それに従って TouchMove イベントが複数回発生します。

https://msdn.microsoft.com/ja-jp/library/ms752279(v=vs.110).aspx
プレビュー イベントはトンネル イベントとも呼ばれ、アプリケーション ルートから、イベントの発生元でありイベント データでソースとして報告される要素へ向かって経路をたどるルーティング イベントです。
特定のイベントがコントロールから生成されるのを抑制し、コンポーネントで定義された別のイベント (より多くの情報を含むイベントや、より具体的な動作を表すイベント) に置き換える場合もあります。


バブルイベントが、イベントの発生元から親要素・親要素…へ伝搬していくのに対して、トンネルイベントはルートの要素からイベント発生元のオブジェクトの順番でイベントが伝搬していきます。(ちょうどトンネルイベントの逆の動きになります)

ルーティングイベントは、RoutedEventArgsのHandledプロパティをtrueにすることで、後続のイベントをキャンセルすることが出来ます。この機能を使うと、トンネルイベントやバブルイベントを途中でインターセプトして後続のイベントの処理をキャンセルすることが出来ます。

 

 

 

TouchDevice.Capture メソッド
https://msdn.microsoft.com/ja-jp/library/dd989302(v=vs.110).aspx
指定した要素へのタッチをキャプチャします。

タッチイベントのcaptureについて
https://code.msdn.microsoft.com/windowsdesktop/CVBXAML-WPF-4-TouchDown-b1018a60

capture ⇒ 捉える、補足する
そのイベントが他に流れないように補足する事(かな?)

TouchDownイベントが発生したら、TouchUpイベントを発生させる。
TouchDeviceのイベントをキャプチャして他に流れないようにする。

ModelParent.FindParent メソッド
https://msdn.microsoft.com/ja-jp/library/microsoft.windows.design.model.modelparent.findparent(v=vs.90).aspx
指定した子の型に対して有効な親を検索します。

ボタンの親のListboxを特定して、listbox_PreviewTouchMoveを故意に発生させ、実態はe.Handled = true で処理をキャンセルする

 

 

ボタンのタッチアップイベントを処分
リストボックスのPreviewTouchMoveイベントを処分
キャプターを解除する。
クリックイベントを発生させ、もともと、TouchEventArgsに入っていたイベントはキャンセルする。

○Xaml全貌

 

○C#コード全貌