2012-01-25 11 views
3

TouchDownイベントでタッチ間のタイムパンを監視してダブルタップを「手動で」キャプチャする方法について別の質問がありましたが、かなりバグがあります。マルチタッチスクリーンでダブルタップをキャプチャする標準的なMicrosoftの方法/イベントを知っている人はいますか?マルチタッチ画面でダブルタップをキャプチャする

どうもありがとう、

ダン

+1

投稿したタイマー実装を試しましたか? http://stackoverflow.com/a/9000217/303612 –

+0

はい、私はこれを試してみました。問題はダブルタップでウィンドウを開いていたことですが、このウィンドウは非表示になっていました。私は一種のあなたの概念を使用して.Activate()メソッドの呼び出しを組み込み、それがすべての並べ替えます。おかげで多くの仲間。 –

答えて

9

私はタップ位置とストップウォッチの組み合わせを確認し、それが完璧に動作します!

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(); 
} 

DoubleTapかどうかは、PreviewTouchDownでチェックされます。

+1

[この](http://www.csharpdeveloping.net/Snippet/How_to_get_distance_between_two_points)私は '' System.Windows.Point'下GetDistanceTo'を見つけることができませんでしたので、私が使用しました – itsho

3

私はたくさんの助けになりました(私の評判があれば、私はそれをアップアップします;)) しかし、調整する必要があったのでダブルタップでしか動作しませんでした。元のコードでは、2を超えるタップはダブルタップとみなされます。 NULL可能に_lastTapLocationを変更し、it'sはダブルタップが助けたときにそれをリセットします。

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; 
    } 
1

私は、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; 
     } 
} 

使用法:Andreasの答えへに追加

private void UIElement_OnStylusSystemGesture(object sender, StylusSystemGestureEventArgs e) 
    { 
     if (e.SystemGesture == SystemGesture.Tap) 
     { 
      if (e.IsDoubleTap(sender as IInputElement)) 
      { 
       // Do your stuff here 
      } 
     } 
    } 
1

は、また、ストップウォッチ関連のコードを削除することができるかもしれません。

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; 
     } 
     return tapsAreCloseInDistance && tapsAreCloseInTime; 
    } 
} 
関連する問題