WPF 工具栏溢出 Touchinteraction 停止应用程序响应输入

WPF Toolbar Overflow Touchinteraction stops App responding to Input

问题描述

当使用触摸(屏幕)输入操作 WPF 工具栏溢出内的按钮时,应用程序停止响应鼠标和触摸输入。键盘输入或任何代码执行(即使在 UI 线程中)似乎不是 affected.Moving 鼠标在 Windows 内容区域之外释放冻结并且应用程序可以再次使用(直到有人使用再次溢出)。

有时它会在第一次交互时直接发生,通常您可以在 "freeze" 发生之前操作几次按钮。

使用鼠标访问 Overflow 内的 Button 时不会发生 "freezing"。

测试环境

我做了一个小测试项目来验证它不是我的应用程序中的东西,我能够验证 .NET 4.5.2、4.6.1 和 4.7 的问题。

已在两台不同的 Windows 7 台具有不同触摸屏的 PC 上进行了测试。两者结果相同。

代码:

<Window x:Class="ToolBarTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:ToolBarTest"
    mc:Ignorable="d"
    Title="MainWindow"
    Height="350"
    Width="525">
<DockPanel>
    <ToolBarTray DockPanel.Dock="Top">
    <ToolBar>
        <Button Content="New" />
        <Button Content="Open" />
        <Button Content="Save" />
    </ToolBar>
    <ToolBar>
        <Button Content="Cut" />
        <Button Content="Copy" />
        <Button Content="Paste" />
        <Button ToolBar.OverflowMode="Always">
            <Grid>
                <TextBlock Text="Testbutton" />
            </Grid>
        </Button>
        </ToolBar>
    </ToolBarTray>
    <TextBox AcceptsReturn="True" />
</DockPanel>

补充想法

对我来说,工具栏或 OverflowToggleButton 似乎在溢出面板关闭后立即捕获鼠标设备。保持溢出面板打开确实可以防止冻结(在我的大应用程序中测试)

我在 MSDN 上交叉发布了这个问题:https://social.msdn.microsoft.com/Forums/de-DE/c4e6061d-ecc1-4c7e-afe9-2587cfd2734d/fenster-bekommt-keine-maus-und-touchevents-mehr-nach-touch-interaktion-mit-toolbar-overflow?forum=wpfde

上述线程中标记答案中的第二个 Link 帮助了我: https://social.msdn.microsoft.com/Forums/de-DE/d964afd2-67d4-4dfb-b118-695ab07ef6c1/wpf-popups-and-touch-input-can-cause-ui-to-become-unresponsive?forum=wpf

基本上在来自 Button 的 Click 事件中,我将 MouseCapture 强制到 Button 并再次释放它:

代码隐藏(不再那么空洞了)

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        CaptureMouse();
        ReleaseMouseCapture();
    }