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.
- public MainPage()
- {
- InitializeComponent();
- TouchPanel.EnabledGestures = GestureType.Tap | GestureType.Hold | GestureType.DoubleTap;
- }
-
- System.Windows.Threading.DispatcherTimer dt;
- public void StartHoldTimer()
- {
- dt = new System.Windows.Threading.DispatcherTimer();
- dt.Interval = new TimeSpan(0, 0, 0, 0, 500);// 500 Milliseconds
- dt.Tick += new EventHandler(dt_Tick);
- dt.Start();
- }
-
- int cnt = 0;
- void dt_Tick(object sender, EventArgs e)
- {
- if (cnt == 3) // 500 ms * 4 == 2 seconds
- {
- cnt = 0;
- GetGesture();
- // disable all events
- TouchPanel.EnabledGestures = GestureType.None;
- // stop the hold timer
- StopHoldTimer();
- }
- cnt++;
- }
-
- void StopHoldTimer()
- {
- dt.Stop();
- cnt = 0;
- }
-
- private void GetGesture()
- {
- if (TouchPanel.IsGestureAvailable)
- {
- GestureSample gs = TouchPanel.ReadGesture();
- if (gs.GestureType == GestureType.Hold)
- {
- string gestureString = string.Format("{0}: {1}", gs.GestureType, gs.Position);
- // Tap and Hold detected, report position
- Debug.WriteLine(gestureString);
- }
- }
- }
-
- private void PhoneApplicationPage_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
- {
- // specify what events the XNA gesture recognizer will look out for
- TouchPanel.EnabledGestures = GestureType.Tap | GestureType.Hold | GestureType.DoubleTap;
- // start the hold timer
- StartHoldTimer();
- }
-
- private void PhoneApplicationPage_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
- {
- // disable all events
- TouchPanel.EnabledGestures = GestureType.None;
- // stop the hold timer
- StopHoldTimer();
- }
Enjoy!
Mike