我目前正在开发使用WPF和(多点触控)电容式触摸屏监视器的应用程序,该监视器被Windows识别为本机触摸设备,即它不需要任何额外的驱动程序。
当我使用WPF按钮并使用触摸点击它时,我收到了一个点击的事件。我的问题是我的一些用户没有执行干净的点击,但是当他们触摸时移动触摸光标的某些像素,所以我的应用程序不再识别点击事件。
有没有办法定义Windows不会将其解释为平移手势的移动阈值,而是将其识别为点击?
答案 0 :(得分:1)
我想出了这个实现-32像素用于定义阈值。
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Willbe.Extensions;
namespace Kiolyn.Wpf
{
public static class TouchAssist
{
public static bool GetTouchAsClick(DependencyObject obj)
=> (bool)obj.GetValue(TouchAsClickProperty);
public static void SetTouchAsClick(DependencyObject obj, bool value)
=> obj.SetValue(TouchAsClickProperty, value);
// Using a DependencyProperty as the backing store for SelectOnMouseOver. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TouchAsClickProperty =
DependencyProperty.RegisterAttached(
"TouchAsClick",
typeof(bool),
typeof(TouchAssist),
new UIPropertyMetadata(false, OnTouchAsClickChanged));
// Using a DependencyProperty as the backing store for SelectOnMouseOver. This enables animation, styling, binding, etc...
private static readonly DependencyProperty LastExecuteTimeProperty =
DependencyProperty.RegisterAttached(
"LastExecuteTime",
typeof(DateTime),
typeof(TouchAssist),
new UIPropertyMetadata(null));
private static readonly DependencyProperty TouchDownPositionProperty =
DependencyProperty.RegisterAttached(
"TouchDownPosition",
typeof(Point),
typeof(TouchAssist),
new UIPropertyMetadata(null));
static void OnTouchAsClickChanged(DependencyObject d, DependencyPropertyChangedEventArgs ev)
{
if (d is Button button)
{
button.IsManipulationEnabled = true;
button.TouchDown += (s, e) =>
{
button.RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, e.Timestamp, MouseButton.Left)
{
RoutedEvent = Mouse.PreviewMouseDownEvent
});
button.ClearValue(LastExecuteTimeProperty);
button.SetValue(TouchDownPositionProperty, e.GetTouchPoint(Application.Current.MainWindow).Position);
};
button.TouchUp += (s, e) =>
{
var command = button.Command;
var parameter = button.CommandParameter;
if (command != null && command.CanExecute(parameter) && button.GetValue(TouchDownPositionProperty) is Point touchDownPosition)
{
var touchUpPosition = e.GetTouchPoint(Application.Current.MainWindow).Position;
var dx = Math.Abs(touchUpPosition.X - touchDownPosition.X);
var dy = Math.Abs(touchUpPosition.Y - touchDownPosition.Y);
if (dx < 32 && dy < 32)
{
// Should be treated as click
// Mark the last execute time
button.SetValue(LastExecuteTimeProperty, DateTime.Now);
command.Execute(parameter);
}
}
};
button.PreviewMouseLeftButtonUp += (s, e) =>
{
if (button.GetValue(LastExecuteTimeProperty) is DateTime lastExecuteTime && DateTime.Now.Subtract(lastExecuteTime).Milliseconds < 300)
{
e.Handled = true;
button.ReleaseMouseCapture();
}
button.ClearValue(LastExecuteTimeProperty);
};
}
}
}
}
用法:
<Button wpf:TouchAssist.TouchAsClick="True"/>