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

How can I combine Touch and Mouse Event Handlers without producing duplicate behavior?

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

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

我想要与此类似的东西 Prevent a WPF application to interpret touch events as mouse events 但仅限于平板电脑。我仍然需要在我的环境中使用我的鼠标。我该如何解决?

按钮示例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>

所以我最终使用了一个很酷的 hack 来完成它。根据 Ahmad 对另一个问题 的回答,我们知道处理程序的开火顺序:

在触控设备上:

TouchDown > PreviewMouseDown > TouchUp > PreviewMouseUp

非触摸:

PreviewMouseDown > PreviewMouseUp

并基于@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;
}

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