在多点触摸屏上捕捉双击触摸
本文关键字:双击 触摸 多点 触摸屏 | 更新日期: 2023-09-27 18:21:17
我发布了另一个问题,即如何通过监控TouchDown事件上触摸之间的时间跨度来"手动"捕获双击,但这很有问题。有人知道微软在多点触摸屏上捕捉双击的标准方式/事件吗?
非常感谢
Dan
我检查了敲击位置和秒表的组合,它非常完美!
private readonly Stopwatch _doubleTapStopwatch = new Stopwatch();
private Point _lastTapLocation;
public event EventHandler DoubleTouchDown;
protected virtual void OnDoubleTouchDown()
{
if (DoubleTouchDown != null)
DoubleTouchDown(this, EventArgs.Empty);
}
private bool IsDoubleTap(TouchEventArgs e)
{
Point currentTapPosition = e.GetTouchPoint(this).Position;
bool tapsAreCloseInDistance = currentTapPosition.GetDistanceTo(_lastTapLocation) < 40;
_lastTapLocation = currentTapPosition;
TimeSpan elapsed = _doubleTapStopwatch.Elapsed;
_doubleTapStopwatch.Restart();
bool tapsAreCloseInTime = (elapsed != TimeSpan.Zero && elapsed < TimeSpan.FromSeconds(0.7));
return tapsAreCloseInDistance && tapsAreCloseInTime;
}
private void OnPreviewTouchDown(object sender, TouchEventArgs e)
{
if (IsDoubleTap(e))
OnDoubleTouchDown();
}
它在PreviewTouchDown中检查它是否为双击。
Jowens的回答对我帮助很大(如果我的声誉允许的话,我会投赞成票;)但我不得不调整它,所以它只适用于双击。原始代码确实认为2以上的任何抽头都是双击。将_lastTapLocation更改为可为null并在双击时将其重置有帮助。
private Point? _lastTapLocation;
private bool IsDoubleTap(TouchEventArgs e)
{
Point currentTapPosition = e.GetTouchPoint(this).Position;
bool tapsAreCloseInDistance = false;
if (_lastTapLocation != null)
{
tapsAreCloseInDistance = GetDistanceBetweenPoints(currentTapPosition, (Point)_lastTapLocation) < 70;
}
_lastTapLocation = currentTapPosition;
TimeSpan elapsed = _doubleTapStopwatch.Elapsed;
_doubleTapStopwatch.Restart();
bool tapsAreCloseInTime = (elapsed != TimeSpan.Zero && elapsed < TimeSpan.FromSeconds(0.7));
if (tapsAreCloseInTime && tapsAreCloseInDistance)
{
_lastTapLocation = null;
}
return tapsAreCloseInDistance && tapsAreCloseInTime;
}
我认为使用StylusSystemGesture事件更合适。这是我的密码。
public static class ext
{
private static Point? _lastTapLocation;
private static readonly Stopwatch _DoubleTapStopwatch = new Stopwatch();
public static bool IsDoubleTap(this StylusSystemGestureEventArgs e, IInputElement iInputElement)
{
Point currentTapPosition = e.GetPosition(iInputElement);
bool tapsAreCloseInDistance = false;
if (_lastTapLocation != null)
{
tapsAreCloseInDistance = GetDistanceBetweenPoints(currentTapPosition, (Point)_lastTapLocation) < 70;
}
_lastTapLocation = currentTapPosition;
TimeSpan elapsed = _DoubleTapStopwatch.Elapsed;
_DoubleTapStopwatch.Restart();
bool tapsAreCloseInTime = (elapsed != TimeSpan.Zero && elapsed < TimeSpan.FromSeconds(0.7));
if (tapsAreCloseInTime && tapsAreCloseInDistance)
{
_lastTapLocation = null;
}
return tapsAreCloseInDistance && tapsAreCloseInTime;
}
}
用法:
private void UIElement_OnStylusSystemGesture(object sender, StylusSystemGestureEventArgs e)
{
if (e.SystemGesture == SystemGesture.Tap)
{
if (e.IsDoubleTap(sender as IInputElement))
{
// Do your stuff here
}
}
}
添加到Andreas的答案中,您还可以删除与Stopwatch相关的代码。
StylusSystemGestureEventArgs还附带了一个Timestamp属性,我相信它以毫秒为单位。
因此,不要使用秒表根据TimeSpan进行计算,而是添加一个int _lastTimestamp
字段并减去时间戳。
public static class ext
{
private static Point? _lastTapLocation;
// Stopwatch changed to int
private int _lastTimestamp = 0;
public static bool IsDoubleTap(this StylusSystemGestureEventArgs e, IInputElement iInputElement)
{
Point currentTapPosition = e.GetPosition(iInputElement);
bool tapsAreCloseInDistance = false;
if (_lastTapLocation != null)
{
tapsAreCloseInDistance = GetDistanceBetweenPoints(currentTapPosition, (Point)_lastTapLocation) < 70;
}
_lastTapLocation = currentTapPosition;
// This replaces the previous TimeSpan calculation
bool tapsAreCloseInTime = ((e.Timestamp - _lastTimestamp) < 700);
if (tapsAreCloseInTime && tapsAreCloseInDistance)
{
_lastTapLocation = null;
}
_lastTimestamp = e.Timestamp;
return tapsAreCloseInDistance && tapsAreCloseInTime;
}
}