2021/02/11

マルチタッチによるクリックの判別

WPF上のタッチ操作でシングルタッチによるものか、マルチタッチによる(指を複数使う)ものかは、Manipulation系のイベントであれば直接判別できるようになっていますが、移動を伴わないTouch系のイベントのときは直接分かるものがないので、どうするか考えてみた話です。

そんなに難しいことでもなく、Touch系のイベントで来るTouchEventArgsのTouchDeviceがイベントを起こした個々のデバイス(指)を示すので、このIdを記録して、これが一連のイベントが終わるまでに一つしか来ていなければシングルタッチ、複数来ていればマルチタッチと判別できます。

以下のButtonの例では、PreviewTouchDownイベントごとにTouchDeviceのIdをHashSetに記録していき、Clickイベントのときに複数来ているか判別した後で、HashSetを初期化しています。なお、タッチ操作の終わりに常にClickイベントが来るわけではないので、PreviewTouchUpイベントを引っ掛けた上で、これはClickイベントより先に来るので、1秒の猶予をおいてから初期化するようにしています。
なお、一つのTouchDeviceがPreviewTouchDownで何回も来ることはないと割り切れば、単なるカウンターでも十分な気はします。

より実用的に、ClickイベントからBehaviorのCallMethodActionを実行するようにしている場合、そのIsEnabled依存関係プロパティとbindingを張ってもいいですが、そのために妙にコードが増えるのもうまくないので、CallMethodActionの分も含めてBehaviorにまとめたのが以下。
サンプル全体は以下。 以上でシングルタッチかマルチタッチかに応じて実行するメソッドを切り替えられるようになりましたが、実際に試してみると、2つの指を合わせて、それぞれ認識されるまでタッチしてから離す(完全に同時にタッチする必要はない)操作は慣れが必要で、タッチデバイスにもよるでしょうが、この操作の実用性自体が少し微妙なことに気づきました。