如何在不产生重复行为的情况下组合触摸和鼠标事件处理程序?
How can I combine Touch and Mouse Event Handlers without producing duplicate behavior?
我正在开发一个在触摸屏平板电脑上使用的 WPF 应用程序。我使用 VS2015 IDE 进行开发,并使用我的鼠标进行调试。
我必须处理按钮的 down
和 up
事件才能执行某些任务。我使用 PreviewMouse
和 PreviewTouch
事件处理程序,但在我使用的每种情况下都有问题:
案例 1: 使用 PreviewMouseDown
、PreviewMouseUp
、PreviewTouchDown
和 PreviewTouchUp
。对于每个按钮,我需要复制我的代码以包含单独的触摸和鼠标事件处理程序 但 完全相同的功能。我这样做是为了让我能够使用应用程序(鼠标)并让用户使用它(触摸)。 问题:触摸事件处理程序执行鼠标事件处理程序;导致应用程序复制行为。例如:一个按 1 递增 x
的按钮,如果您 "Click" 它会递增 1,但如果您 "Touch" 它会递增 2。
案例 2: 使用 Click
、PreviewMouseUp
和 PreviewTouchUp
。 问题: PreviewTouchUp
和 PreviewMouseUp
在 鼠标单击 时没有被调用。
案例 3: 为每个按钮创建一个方法,并从触摸和鼠标事件中调用它,例如 How to get Touchscreen to use Mouse Events。 问题:重复行为(方法被调用两次)
情况 4: 删除所有 Touch 事件,因为 PreviewMouseDown
和 PreviewMouseUp
正在任何 Touch 上执行。该行为有效,但我需要触摸按钮上的某些位置才能执行。 (透明度?我必须准确地触摸一个位置 - 就像鼠标一样?)
案例 5: 使用 MouseUp
和 MouseDown
而不是 Preview
。 Touch 根本不起作用,触摸按钮上的任何位置。
我想要与此类似的东西 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 将是启动已提升触摸的触摸设备。
我正在开发一个在触摸屏平板电脑上使用的 WPF 应用程序。我使用 VS2015 IDE 进行开发,并使用我的鼠标进行调试。
我必须处理按钮的 down
和 up
事件才能执行某些任务。我使用 PreviewMouse
和 PreviewTouch
事件处理程序,但在我使用的每种情况下都有问题:
案例 1: 使用
PreviewMouseDown
、PreviewMouseUp
、PreviewTouchDown
和PreviewTouchUp
。对于每个按钮,我需要复制我的代码以包含单独的触摸和鼠标事件处理程序 但 完全相同的功能。我这样做是为了让我能够使用应用程序(鼠标)并让用户使用它(触摸)。 问题:触摸事件处理程序执行鼠标事件处理程序;导致应用程序复制行为。例如:一个按 1 递增x
的按钮,如果您 "Click" 它会递增 1,但如果您 "Touch" 它会递增 2。案例 2: 使用
Click
、PreviewMouseUp
和PreviewTouchUp
。 问题:PreviewTouchUp
和PreviewMouseUp
在 鼠标单击 时没有被调用。案例 3: 为每个按钮创建一个方法,并从触摸和鼠标事件中调用它,例如 How to get Touchscreen to use Mouse Events。 问题:重复行为(方法被调用两次)
情况 4: 删除所有 Touch 事件,因为
PreviewMouseDown
和PreviewMouseUp
正在任何 Touch 上执行。该行为有效,但我需要触摸按钮上的某些位置才能执行。 (透明度?我必须准确地触摸一个位置 - 就像鼠标一样?)案例 5: 使用
MouseUp
和MouseDown
而不是Preview
。 Touch 根本不起作用,触摸按钮上的任何位置。
我想要与此类似的东西 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 将是启动已提升触摸的触摸设备。