Search code examples
c#winformsscrolltouchwindows-10

Vertical swipe simulated mouse events sent to wrong control in Windows Forms app on Windows 10 tablet


I'm trying to run a Windows Forms app on a Windows 10 tablet (Dell Venue 8 Pro). In general, Windows translates touch events into the obvious mouse event counterparts. However, it's doing something strange with vertical swipes.

My app has a custom control (derived directly from Control with a call to SetStyle(ControlStyles.Selectable..., true) in its constructor) that shows graphics rendered by Direct3D. The control interprets MouseDown -> MouseMove -> MouseUp sequences as requests to rotate the view about the lookat position. This works fine on the desktop, but on a tablet it breaks: vertical swipes on my custom control are somehow being caught by Windows and passed to a nearby DataGridView, where they are interpreted as requests to scroll through the table. The DataGridView and my control are not siblings under the same container; they are at completely different levels of the control hierarchy. Here's a screenshot:

Screenshot of the application showing the different interpretations of vertical and horizontal swipes

I've done some debugging to prove to myself that no mouse events are making it to my control during the vertical swipe. A few trickle in right when I lift my finger, but during the vertical swipe there's nothing.

The trouble seems to be that my code (in the event handlers) simply isn't getting run because no input is making its way to my control.

What is going on here, and is there any way I can tell Windows not to send vertical swipe events that happen over my control to a completely unrelated control?

Edit: I should add that I'm calling Focus() all over the place in my code to make sure my control is focused while the mouse is over it. I put it in OnMouseMove, OnMouseDown, and pretty much on every other mouse event.

Edit: I have built a small Visual Studio 2010 solution demonstrating this problem. It's too much code to reproduce here inline, but it's easy to grok. Build it, install it on a Windows 10 tablet, and try swiping vertically in the rightmost control. Note that rather than that control receiving a bunch of mouse events, the DataGridView fires Scroll.

Update: I've explicitly tested whether my control is focused when the DataGridView gets a Scroll event. If I call Focus() on my control in response to MouseMove etc. as mentioned above, my control does get the focus and holds it during the vertical swipe while DataGridView.Scroll is firing. In the DataGridView.Scroll event handler, I have printed out whether my control is focused, and it is. So this is not a matter of the DataGridView stealing focus; it's a matter of the DataGridView handling a swipe intended for my control even when my control is focused.

Note: If I set dataGridView.ScrollBars to ScrollBars.None, the mouse events for the swipe do go to my control. I've been messing with ugly hacks that hide the scrollbars every time my control gets focused and show them every time the DataGridView gets focused. But they're all ugly hacks with unpleasant side effects.


Solution

  • How about handling touch events on your own, and not await a proper implementation of Microsoft of it's own. link