1. Problem
You need to understand what gestures are and how to use them in your Silverlight Windows Phone 7 application.
2. Solution
Various techniques are
available for enabling you to know where a user touched the screen and
how many fingers were used. You can use the Touch static class, which provides the FrameReported event rose when the screen is touched. Along with the Touch static class, you can use the GetTouchPoints method from the TouchFrameEventArgs argument provided by the FrameReported event handler. The GetTouchPoints method returns a TouchPointCollection collection filled with TouchPoint objects representing touched screen points.
But using the TouchPointCollection
to understand gestures is not so easy. You have to study the collection
to understand how the user's fingers have moved on the screen and what
that user's intentions could be. You should use—along with the Touch.FrameReported event handler—the TouchPanel class included in the XNA framework. The TouchPanel class, along with the GestureSample structure, really simplifies the recognition of gestures by your application (see Figure 1 for diagrams of these classes).
3. How It Works
Gestures are operations carried
out with one or more fingers on the phone's touch screen. Windows Phone
supports having at least four fingers on the screen. A finger can touch
the screen and immediately rise up, or it can touch the screen and move
in any direction while remaining pressed on the screen. Each operation
that the user's fingers perform on the touch screen represents a
gesture. In Table 1, you can see the list of supported gestures. The most used are Tap, Double Tap, Pinch and Flick.
Most Silverlight controls provide Click and Double Click
event handlers when the user taps and double-taps on the control
itself, but you might need other gestures in your application. For
example, imagine a book reader application in which the user needs to
scroll through pages quickly. Implementing a Tap gesture to scroll page
by page would be frustrating for the user. Much better: the Flick
gesture, which returns finger-moving speed with the Delta property provided by the GestureSample structure. You could use this Vector2 value returned by the Delta property to enable the user to move faster across the book pages.
Table 1. All the gestures provided by the GestureType enumeration
Gesture | Description |
---|
Tap | The finger touches and immediately rises up from the touch screen. |
Double Tap | The same as the Tap gesture, but touching and rising two times, one right after the other. |
Horizontal Drag | The finger touches the screen, continues to press it, and moves horizontally. |
Vertical Drag | The same as Horizontal Drag, but the movement is vertical. |
Free Drag | The finger touches the screen, continues to press it, and moves freely. |
Drag Complete | The finger starts a drag gesture and completes it by raising the finger. |
Flick | The finger touches the screen and moves either up or down very fast. This is the gesture used to quickly remove the lock screen. |
Pinch | Two
fingers touch the screen, moving either apart or together. This is the
gesture used to either zoom into or zoom out from an image. |
Pinch Complete | Two fingers start the Pinch gesture and complete it by raising both fingers. |
Hold | The finger touches the screen and continues to press it without moving. |
To use gestures in your application, you first need to complete the following steps:
Add a reference to both the Microsoft.Xna.Framework.dll and Microsoft.Xna.Framework.Input.Touch.dll assemblies.
Define a FrameReported event handler.
Define all the gestures you want to trap in your application by specifying them in the EnabledGestures property from the TouchPanel class separated by the OR logical operator.
In the FrameReported event handler, check whether a gesture is available by using the IsGestureAvailable property from the TouchPanel class.
Define a GestureSample object that receives gestures from the ReadGesture method provided by the TouchPanel class.
Use the gesture accordingly in your application.
4. The Code
To demonstrate every
gesture provided by the phone, we have created a simple application that
writes the gesture type on the page title.
Start Visual Studio 2010 and create a new Silverlight Windows Phone 7 application called GesturesDemo. In the MainPage.xaml file, add a row definition to the content grid, specifying a new row with the Height property equal to Auto. Inside the content grid, add an image that fills the entire grid.
. . .
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image x:Name="imgBackground" Grid.Row="0" Stretch="Fill"
Source="/images/background.jpg"/>
</Grid>
. . .
NOTE
We have added an image control just to give to the application a better
look but the image control is not necessary to retrieve gestures. The Touch.FrameReported event is the only one that catches gestures because it is implemented into the PhoneApplicationFrame class.
The MainPage.xaml.cs file—more specifically, in the MainPage
constructor—contains the necessary instructions for defining the
gestures that you need to catch. In our case, we want to catch all the
available gestures, so we specify them all, separating them by the OR logical operator in the EnabledGestures property. Moreover, the FrameReported event is defined and managed by the Touch_FrameReported event handler.
. . .
// Constructor
public MainPage()
{
InitializeComponent();
Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);
TouchPanel.EnabledGestures = GestureType.Tap
| GestureType.DoubleTap
| GestureType.Flick
| GestureType.Pinch
| GestureType.HorizontalDrag
| GestureType.VerticalDrag
| GestureType.PinchComplete
| GestureType.DragComplete
| GestureType.Hold
| GestureType.FreeDrag;
}
In the Touch_FrameReported event handler, the IsGestureAvailable property is checked to determine whether a gesture has been caught by the frame. If it has, the ReadGesture method is used to retrieve a GestureSample object. This object contains useful information (via the GestureType
property) indicating which gesture has been performed by the user, and
eventually extra information depending on the gesture type. For example,
in our code when the Flick gesture occurs, we also print on the screen
the Delta property.
The TouchFrameEventArgs parameter provided by the FrameReported event contains some cool information, such as a TimeSpan value set to the time—when the gesture has occurred. This gesture has been used in the 7Drum application to store drum component playing sequences and the times when they occur.
void Touch_FrameReported(object sender, TouchFrameEventArgs e)
{
if (TouchPanel.IsGestureAvailable)
{
GestureSample gesture = TouchPanel.ReadGesture();
PageTitle.Text = gesture.GestureType.ToString();
if (gesture.GestureType == GestureType.Flick)
PageTitle.Text += " " + gesture.Delta.ToString();
}
}
5. Usage
In this recipe, you need a
physical device to test the application. Indeed, the emulator is not
able to intercept multi-touch gestures such as the Pinch.
Connect your unlocked
device and run the application from Visual Studio 2010, ensuring that the
output target is set to Windows Phone 7 Device. The application will
start, showing the output in Figure 2.
At this point, you can start playing with your phone. In Figure 3, we performed a very rapid Flick, as demonstrated by the page title showing the gesture type and the Delta property value.