Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Control animation while navigating between panes inside a Windows Phone page

From Wiki
Jump to: navigation, search

This article explains how to add a gesture driven settings pane inside your windows phone app like the one used in the official Facebook app for Windows Phone

WP Metro Icon UI.png
WP Metro Icon Tools.png
SignpostIcon XAML 40.png
WP Metro Icon WP8.png
SignpostIcon WP7 70px.png
Article Metadata
Code ExampleTested with
SDK: Windows Phone SDK 8.0
Devices(s): Nokia Lumia 820
CompatibilityArticle
Created: Depechie (01 Aug 2013)
Last edited: hamishwillee (07 Aug 2013)

Contents

Introduction

In this article we will show you how to add a settings pane to your windows phone main page that can be made visible by swiping from left to right.
So we are going to handle these gestures ourselves, to control the animation and set the same specific look and feel like the one in the Facebook app.

Detail

To start, open up Visual Studio and create a new Windows Phone app by selecting the Windows Phone Databound App template. This template will give us a filled main page, with a listbox containing data.

Open the MainPage.xaml so we can add the Settings Pane xaml! It's an extra grid inside the main Container grid that is placed outside the viewing field by setting its margin to -860 and limiting the width to 380.

Place the following xaml above the LayoutRoot grid:

<Grid x:Name="SettingsPane" Background="Teal" Grid.Row="0" Margin="-860,0,0,0" Width="380">
<Grid.Projection>
<PlaneProjection/>
</Grid.Projection>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
 
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="SETTINGS PANE WITH GESTURES" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="swipe for main &gt;" Margin="9,-7,0,0" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
</StackPanel>
</Grid>

Now to be able to interact with user gestures, we will be adding the GestureListener class of the Windows Phone Toolkit. The toolkit can be added by using NuGet or download it from CodePlex

Warning.pngDISCLAIMER: Even though it is noted that the GestureListener class is deprecated, I still find it more easy to use than working with the build in gesture development functions of Windows Phone 8.

Place the following xaml underneath the Container grid:

<Grid x:Name="Container" Background="Transparent">
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener DragDelta="GestureListener_OnDragDelta" DragCompleted="GestureListener_OnDragCompleted" />
</toolkit:GestureService.GestureListener>

Don't forget to add the namespace reference to the toolkit on top!

xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"

You’ll notice that with this, we are hooking into the DragDelta and DragCompleted events. We are going to use these events to animate our page.

In the OnDragDelta event we will check to see if there has been a Horizontal gesture detected and if so, depending on what pane is already open, show this drag animation on screen! Take a look at the code below and you’ll notice some tricks to get this done!

Basically we calculate how far the user is dragging the content and if he get’s passed DragDistanceToOpen (or ToClose), we will start the rest of the animation. If he's not passed this distance parameter we'll adjust the HorizontalOffset of the container grid corresponding the dragged offset, this will show us the drag interaction/animation on screen.

The code for the OnDragDelta is placed inside the code behind page of MainPage.xaml

private double _dragDistanceToOpen = 75.0;
private double _dragDistanceToClose = 305.0;
private double _dragDistanceNegative = -75.0;
 
private void GestureListener_OnDragDelta(object sender, DragDeltaGestureEventArgs e)
{
if (e.Direction == System.Windows.Controls.Orientation.Horizontal && e.HorizontalChange > 0 && !_isSettingsOpen)
{
double offset = _feContainer.GetHorizontalOffset().Value + e.HorizontalChange;
if (offset > _dragDistanceToOpen)
this.OpenSettings();
else
_feContainer.SetHorizontalOffset(offset);
}
if (e.Direction == System.Windows.Controls.Orientation.Horizontal && e.HorizontalChange < 0 && _isSettingsOpen)
{
double offsetContainer = _feContainer.GetHorizontalOffset().Value + e.HorizontalChange;
if (offsetContainer < _dragDistanceToClose)
this.CloseSettings();
else
_feContainer.SetHorizontalOffset(offsetContainer);
}
}

Now next, we use the OnDragCompleted to finalize our animation, it’s almost the same code as above. The only difference now is that if the user has stopped his gesture and he has not passed the given distance, we will reset the content to it’s original position. Giving us a ‘snap back’ animation.

private void GestureListener_OnDragCompleted(object sender, DragCompletedGestureEventArgs e)
{
if (e.Direction == System.Windows.Controls.Orientation.Horizontal && e.HorizontalChange > 0 && !_isSettingsOpen)
{
if (e.HorizontalChange < _dragDistanceToOpen)
this.ResetLayoutRoot();
else
this.OpenSettings();
}
if (e.Direction == System.Windows.Controls.Orientation.Horizontal && e.HorizontalChange < 0 && _isSettingsOpen)
{
if (e.HorizontalChange > _dragDistanceNegative)
this.ResetLayoutRoot();
else
this.CloseSettings();
}
}

Forcing the rest of the animation is done in the OpenSettings() and CloseSettings() methods and resetting the screen to its original state, is done in the ResetLayoutRoot() method

private bool _isSettingsOpen = false;
 
private void OpenSettings()
{
var trans = _feContainer.GetHorizontalOffset().Transform;
trans.Animate(trans.X, 380, TranslateTransform.XProperty, 300, 0, new CubicEase
{
EasingMode = EasingMode.EaseOut
});
_isSettingsOpen = true;
}
 
private void CloseSettings()
{
var trans = _feContainer.GetHorizontalOffset().Transform;
trans.Animate(trans.X, 0, TranslateTransform.XProperty, 300, 0, new CubicEase
{
EasingMode = EasingMode.EaseOut
});
_isSettingsOpen = false;
}
 
private void ResetLayoutRoot()
{
if (!_isSettingsOpen)
_feContainer.SetHorizontalOffset(0.0);
else
_feContainer.SetHorizontalOffset(380.0);
}

If you try this in your code you will see that some methods are still missing! This because we are using some extension methods: SetHorizontalOffset(), GetHorizontalOffset() and Animate() the actual code is in the example solution provided below.

Note.pngNote: I'm not taking credit for these extension methods - they were created by Colin Eberhardt (you can follow him on twitter @ColinEberhardt or take a look at his blog)

So with that in place you'll get a nice gesture driven settings pane!

Video Demo

The media player is loading...

Downloads

A complete working solution can be downloaded here: File:SettingsPageAnimation solution.zip

Summary

We talked about how to use gesture commands to animate you windows phone page, by doing so we are mimicking the settings pane feature used in the official Facebook app for windows phone.

This page was last modified on 7 August 2013, at 04:10.
393 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×