Home > OS >  PreviewMouseLeftButtonDown event occasionally fires when touching outside the control
PreviewMouseLeftButtonDown event occasionally fires when touching outside the control

Time:11-17

I have a WPF TextBox with a PreviewMouseLeftButtonDown event handler running on a laptop with a touch screen.

When I touch the TextBox the event handler fires as expected. However, if I then touch somewhere else in the application the event will fire after 8 or 9 touches. It seems that .NET thinks the control has been directly touched even though the touch is not on top of the TextBox control. From what I can tell, the sender and mouse event args of the event handler don't show any identifiable difference between legitimate TextBox touches and the 9th touch outside the control.

This can easily be reproduced in a standalone application (see code and steps below):

  1. Touch the TextBox once. A new window should open to show the event fired.
  2. Close the window created by the event handler
  3. Touch anywhere in the application window that is NOT the TextBox 9 times.
  4. A window should open again which means the event fired.
public MainWindow()
{
    InitializeComponent();            
    MyTextBox.PreviewMouseLeftButtonDown  = MyTextBox_PreviewMouseLeftButtonDown;
}

private void MyTextBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    var win = new Window();
    win.ShowDialog();
}
  • Is there any explanation for why a touch outside of a control can sometimes trigger a control's mouse event in .NET?
  • Is there a workaround for this issue so that both touch and mouse can be supported without false positive event triggers?

CodePudding user response:

Figured out the solution after more searching.

This is a known bug (see https://github.com/dotnet/wpf/issues/2491).

The workaround is to execute the ShowDialog() code within a Dispatcher.BeginInvoke() call in the event handler.

The theory behind what might be happening is that changing focus to a new window during the event handler causes the control to continue thinking it's in a "touch down" state. When a subsequent touch is made WPF thinks it's the "second finger" of a multi touch operation and creates another handler. It does this until all "ten fingers" have been pressed. After that, it cycles back to the first handler. Since the control still thinks it's being touched it will fire when your "first finger" touches anywhere on the application.

This explains why the event triggers consistently after 9 touches outside the text box and why invoking the ShowDialog after the event handler finishes fixes the problem.

  • Related