Windows Phone 7: Detecting Tap and Hold

There are a couple of ways to go about detecting Tap and Hold in Windows Phone 7. This method uses the XNA Touch Gesture recognizer (Microsoft.Xna.Framework.Input.Touch) in a Silverlight application.  The touch gesture recognizer can tell the difference between tap, double-tap,  and hold gestures. Additionally, using the XNA gesture recognizer you don’t need to worry about mistaking a pan/drag for a hold: if you move your finger too much, a tap or hold won’t be recognized. Other solutions involve inferring these events through the use of a timer.  A common application of this is to implement a context menu in your Windows Phone 7 application.

This method handles the ManipulationStarted event to detect the initial tap. In this event, you tell the gesture recognizer which gestures you want to monitor. In this case, tap, double-tap, and hold.  (This is also done in the constructor of the page, to initialize the recognizer.)

Next a 500 ms timer is started. The timer is used to detect when enough ‘hold time’ has elapsed. When the ‘hold time’ threshold is met, the gesture is detected, the gesture recognizer is reset, and the timer is stopped. This is where you would invoke the context menu. (Not implemented here.) A timer is only necessary here for the implementation of a context-menu. You could detect the gesture in the ManipulationCompleted event handler, which fires when the user releases their finger from the screen.

  1. public MainPage()
  2. {
  3.     InitializeComponent();
  4.     TouchPanel.EnabledGestures = GestureType.Tap | GestureType.Hold | GestureType.DoubleTap;
  5. }
  6.  
  7. System.Windows.Threading.DispatcherTimer dt;
  8. public void StartHoldTimer()
  9. {
  10.     dt = new System.Windows.Threading.DispatcherTimer();
  11.     dt.Interval = new TimeSpan(0, 0, 0, 0, 500);// 500 Milliseconds
  12.     dt.Tick += new EventHandler(dt_Tick);
  13.     dt.Start();
  14. }
  15.  
  16. int cnt = 0;
  17. void dt_Tick(object sender, EventArgs e)
  18. {
  19.     if (cnt == 3) // 500 ms * 4 == 2 seconds
  20.     {
  21.         cnt = 0;
  22.         GetGesture();
  23.         // disable all events
  24.         TouchPanel.EnabledGestures = GestureType.None;
  25.         // stop the hold timer
  26.         StopHoldTimer();
  27.     }
  28.     cnt++;
  29. }
  30.  
  31. void StopHoldTimer()
  32. {
  33.     dt.Stop();
  34.     cnt = 0;
  35. }
  36.  
  37. private void GetGesture()
  38. {
  39.     if (TouchPanel.IsGestureAvailable)
  40.     {
  41.         GestureSample gs = TouchPanel.ReadGesture();
  42.         if (gs.GestureType == GestureType.Hold)
  43.         {
  44.             string gestureString = string.Format("{0}: {1}", gs.GestureType, gs.Position);
  45.             // Tap and Hold detected, report position
  46.             Debug.WriteLine(gestureString);
  47.         }
  48.     }
  49. }
  50.  
  51. private void PhoneApplicationPage_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
  52. {
  53.     // specify what events the XNA gesture recognizer will look out for
  54.     TouchPanel.EnabledGestures = GestureType.Tap | GestureType.Hold | GestureType.DoubleTap;
  55.     // start the hold timer
  56.     StartHoldTimer();
  57. }
  58.  
  59. private void PhoneApplicationPage_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
  60. {
  61.     // disable all events
  62.     TouchPanel.EnabledGestures = GestureType.None;
  63.     // stop the hold timer
  64.     StopHoldTimer();
  65. }

Enjoy!

Mike

This work is licensed under a Creative Commons license.

Leave a Reply

Your email address will not be published. Required fields are marked *