如何在不产生重复行为的情况下结合触摸和鼠标事件处理程序?

Kha*_*laf 5 c# wpf touch

我正在开发一个用于触摸屏平板电脑的 WPF 应用程序。我使用 VS2015 IDE 进行开发,并使用鼠标进行调试。

我必须处理按钮downup事件来执行某些任务。我使用PreviewMousePreviewTouch事件处理程序,并且在我使用的每种情况下都有问题:

  • 案例1:使用PreviewMouseDownPreviewMouseUpPreviewTouchDownPreviewTouchUp。对于每个按钮,我需要复制我的代码以包含单独的触摸和鼠标事件处理程序,功能完全相同。我这样做是为了我能够使用应用程序(鼠标)和用户使用它(触摸)。问题:触摸事件处理程序执行鼠标事件处理程序;导致应用程序复制行为。例如:一个增加一的按钮,x如果你“点击”它会增加一但如果你“触摸”它会增加二。

  • 情况 2:使用Click,PreviewMouseUpPreviewTouchUp问题:PreviewTouchUpPreviewMouseUp不被调用的鼠标点击

  • 案例 3:为每个按钮创建一个方法,并从 Touch 和 Mouse 事件中调用它,例如How to get Touchscreen to use Mouse Events问题:重复行为(方法被调用两次)

  • 案例4:自删除所有触摸事件,PreviewMouseDownPreviewMouseUp正在对任何触摸执行。该行为有效,但我需要触摸按钮上的某些位置才能执行。(透明?我必须只触摸一个位置——就像一只鼠标?)

  • 案例 5:使用MouseUpandMouseDown代替Preview. 根本没有在 Touch 上工作,触摸按钮上的任何位置。

我想要类似的东西,防止 WPF 应用程序将触摸事件解释为鼠标事件,但仅限于平板电脑。我仍然需要在我的环境中使用我的鼠标。我该如何解决?

按钮示例 XAML:

<Button x:Name="locationScrollUpButton" Margin="0,5,5,0" Background="Transparent" Padding="0" Grid.Row="1" Grid.Column="1" PreviewMouseUp="locationScrollUpButton_PreviewMouseUp" PreviewMouseDown="locationScrollUpButton_PreviewMouseDown" BorderThickness="0" PreviewTouchDown="locationScrollUpButton_PreviewTouchDown" PreviewTouchUp="locationScrollUpButton_PreviewTouchUp" >
    <StackPanel>
        <TextBlock x:Name="locationUpButtonText" Text="Up" FontSize="13" Margin="0,2,0,4" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        <Image x:Name="locationUpButtonImage" Source="/ProjectName;component/Resources/CaptureView/Location-Scroll-Up-White.png" Width="55" Height="60"/>
    </StackPanel>
</Button>
Run Code Online (Sandbox Code Playgroud)

小智 9

检查 MouseEventArgs 的 StylusDevice 属性。如果它为空,则鼠标事件不是提升的触摸事件。如果它不为空,则 StylusDevice 将是启动被提升的触摸的触摸设备。


Kha*_*laf 4

所以我最终使用了一个很酷的技巧来做到这一点。根据艾哈迈德对另一个问题的回答我们知道处理程序的开火顺序:

在触摸设备上:

触摸按下 > 预览鼠标按下 > 触摸向上 > 预览鼠标向上

非触摸时:

预览鼠标按下 > 预览鼠标向上

并基于@M.Kazem 的评论。现在修复看起来像这样:

private bool ButtonPreview = true;
private void Button_TouchDown(object sender, TouchEventArgs e)
{
    // task 1
    ButtonPreview = false;
}
private void Button_TouchUp(object sender, TouchEventArgs e)
{
    // task 2
    // ..
}
private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    if (ButtonXPreview)
    {
        // task 1
    }
    else
        ButtonXPreview = true;

}
private void Button_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
    if (ButtonXPreview)
    {
        // task 2
    }
    else
        ButtonXPreview = true;
}
Run Code Online (Sandbox Code Playgroud)