Unlike desktop applications which use a keyboard and mouse, Windows Phone applications use touch screen gestures for input. The most common gesture is the Tap, which is the same as a Click and uses the Click event handler. Today, I'll be writing about four gestures: Pan, Flick, Pinch and Stretch, which are implemented in the ManipulationDelta and ManipulationCompleted event handlers. To illustrate how they work, I'll use a modification of the previous slideshow sample and add the gestures handlers to change the Scale and Translate transform values of the image.
To briefly explain what these gestures are:
Since it is possible in this sample to move the image off the screen, or pinch it into a size that is too small to resize back, I've added a button to revert to default. Below is what it looks like after a couple of Flicks to get to the Penguins, a Stretch to resize the image larger, and a Pan to move the image down and centered on the penguins:
Xaml:
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Canvas x:Name="ContentGrid">
<Image x:Name="Image1" Source="Koala.jpg" ManipulationDelta="Image1_ManipulationDelta" ManipulationCompleted="image1_ManipulationCompleted">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="scale" ScaleX="0.47" ScaleY="0.47" />
<TranslateTransform x:Name="translate" />
</TransformGroup>
</Image.RenderTransform>
</Image>
</Canvas>
<Button Content="Revert to Default" Grid.Row="1" Click="Button_Click" />
</Grid>
Code:
public partial class MainPage : PhoneApplicationPage
{
List<string> files = new List<string>() { "Koala.jpg", "Jellyfish.jpg", "Penguins.jpg" };
List<BitmapImage> images = new List<BitmapImage>();
int current = 0;
// Constructor
public MainPage()
InitializeComponent();
foreach (string file in files)
BitmapImage image = new BitmapImage(new Uri(file, UriKind.Relative));
images.Add(image);
}
private void image1_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
//if a pan or flick gesture, scale is 0
if (e.TotalManipulation.Scale.X == 0 && e.TotalManipulation.Scale.Y == 0)
//if event occurs during inertia, it is a flick, so go to the previous or next image
if (e.IsInertial)
//use the X translation to determine whether to go to previous or next
double translation = e.TotalManipulation.Translation.X;
if (translation > 0)
Previous();
else
Next();
//revert the translate from the ManipulationDelta event so that only the image source changes
translate.X -= e.TotalManipulation.Translation.X;
translate.Y -= e.TotalManipulation.Translation.Y;
private void Image1_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
//handle stretch or pinch gestures by changing the scale
if (e.DeltaManipulation.Scale.X != 0 && e.DeltaManipulation.Scale.Y != 0)
scale.ScaleX *= e.DeltaManipulation.Scale.X;
scale.ScaleY *= e.DeltaManipulation.Scale.Y;
//handle pan gesture
translate.X += e.DeltaManipulation.Translation.X;
translate.Y += e.DeltaManipulation.Translation.Y;
private void Button_Click(object sender, RoutedEventArgs e)
scale.ScaleX = 0.45;
scale.ScaleY = 0.45;
translate.X = 0;
translate.Y = 0;
private void Previous()
current--;
if (current < 0)
current = files.Count - 1;
Image1.Source = images[current];
private void Next()
current++;
if (current >= files.Count)
current = 0;