wpf: Click event is rarely raised when using touch

  • .NET Core Version: 3.0.100-preview-009812
  • Windows version: Version 1803
  • Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes

Problem description: Click event is rarely raised when using touch in new windows.

Actual behavior: Touching (clicking) the button does nothing the first 10 times. 11th time the click event is raised.

Expected behavior: Click event on button should be raised on first touch.

Minimal repro: Touch.zip MainWindow.xaml:

<Window 
    x:Class="Touch.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="400" Width="400">
    <StackPanel>
        <TextBox Text="{Binding Integer}" FontSize="48" />
        <TextBox Text="{Binding Integer}" FontSize="48" />
    </StackPanel>
</Window>

MainWindow.xaml.cs:

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();

        DataContext = new ViewModel();
    }
}

ViewModel.cs:

public class ViewModel
{
    private int _integer;

    public int Integer
    {
        get => _integer;
        set
        {
            _integer = value;
            new DialogWindow().ShowDialog();
        }
    }
}

DialogWindow.xaml:

<Window
    x:Class="Touch.DialogWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="200" Width="200">
    <Grid>
        <Button Content="Close" Click="OnClick" />
    </Grid>
</Window>

DialogWindow.xaml.cs:

public partial class DialogWindow
{
    public DialogWindow()
    {
        InitializeComponent();
    }

    private void OnClick(object sender, RoutedEventArgs e)
    {
        Close();
    }
}

When one of the textboxes has content changed, and you uses touch to focus the other textbox, the DialogWindow will pop up. Now the problem occurs, and we have to press (touch) the close button multiple times (etc. 11 times on one of our devices) before the click event happens and the dialog closes.

TouchDown event works properly. We’re also experincing this on other elements than Button, for example TextBox. It is therefore not a solution to switch to TouchDown event. Everyhing in the new window seems to be buggy.

Related links: https://stackoverflow.com/questions/53851382/wpf-click-event-is-not-raised-on-touch-screen https://stackoverflow.com/questions/28441538/touching-a-wpf-button-does-sometimes-not-invoke-the-click-handler-under-windows

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 11
  • Comments: 20 (4 by maintainers)

Most upvoted comments

@stevenbrix Touch is not first class in WPF as it is in UWP. If touch doesn’t promote to mouse (and therefore click) the button will not click.

Disabling the RealTimeStylus works with me. See the next article: “… As a result, to use WM_TOUCH to receive touch messages from a WPF window, you must disable the built-in stylus support in WPF …” https://docs.microsoft.com/en-us/dotnet/desktop/wpf/advanced/disable-the-realtimestylus-for-wpf-applications

You should, instead, use this AppContext switch:

https://github.com/dotnet/wpf/blob/ad2c2211e18283870b5d50eccdb32c1905425951/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/CoreAppContextSwitches.cs#L39

This is much cleaner and is present in .NET Framework 4.8 as well as version of .NET Core (and beyond) that support WPF. I believe it is also available in .NET Framework 4.7.2, but I don’t have the history to hand right now so I don’t feel comfortable stating that as fact. If you enable the switch and you try to access Tablet.TabletDevices they should be empty, even on a machine with touch/stylus devices. Then you know its working and WPF (via WISP) will not eat various touch-centric Windows messages.

Slightly offtopic, but here is how we are doing modal loops without ShowDialog in WinForms. It’s how PropertyGrid shows its dropdown popups. No idea if it helps with this particular problem.

@hunterzzzpro yeah approach with overlay is actually ok for us, but Show() not blocking until dialog is closed is kind of a problem.

Actually now that I think about it, probably the fact that Show() (and thus really the main window’s message loop) does not wait for the dialog to close is exactly why it works for you.

Hello are there any workarounds or fixes of this bug available?

I seems to be related to that issue 450. At the moment you click the close button in dialog and it doesn’t work you can see that it has 0 TouchesOver on MainWindow but 2 TouchesOver on DialogWindow. This is not correct as I only ever touched the screen with 1 finger at a time.

I don’t know exactly how .NET handles touch internally but I feel the same part of WPF code is responsible for both cases.