December09

Click back twice to exit app?

I have been adding animations to a Windows Phone 7 app that has a panorama control and ran into a problem I have seen others post online.  I figured it out, so I thought I would take a minute to explain how.

Get ready to add transitions

The Silverlight Toolkit is the way you want to go about adding quick and easy animations when a page loads and navigates away from the current page.

If you are not familiar with the basics visit the link above, or read this really good tutorial about wp7 page transitions on Windows Phone Geek.

The basics are that you have to include the toolkit, and you have to modify the root frame of your application to be a transition page instead of a normal phone page.

In a typical application you have the RootFrame declared in your App.xaml.cs like this:

    public partial class App : Application
    {
        /// <summary>
        /// Provides easy access to the root frame of the Phone Application.
        /// </summary>
        /// <returns>The root frame of the Phone Application.</returns>
        public PhoneApplicationFrame RootFrame { get; private set; }
    }

But for transitions to happen you need to change the object to a TransitionFrame when your InitializePhoneApplication is called.

            // REPLACE THE FIRST LINE WITH THE SECOND
            // RootFrame = new PhoneApplicationFrame();
            RootFrame = new TransitionFrame();

This will give you the ability to add transitions to your page.

I prefer to define my transition style at the application level, rather than the page level.  Usually I want all the pages to behave the same, so this gives a nice central point for all of them to reference it.

In your App.xaml add a style like this:

        <Application.Resources>
            <Style x:Key="TransitionPageStyle" TargetType="phone:PhoneApplicationPage">
            <Setter Property="toolkit:TransitionService.NavigationInTransition">
                <Setter.Value>
                    <toolkit:NavigationInTransition>
                        <toolkit:NavigationInTransition.Backward>
                            <toolkit:TurnstileTransition Mode="BackwardIn"/>
                        </toolkit:NavigationInTransition.Backward>
                        <toolkit:NavigationInTransition.Forward>
                            <toolkit:TurnstileTransition Mode="ForwardIn"/>
                        </toolkit:NavigationInTransition.Forward>
                    </toolkit:NavigationInTransition>
                </Setter.Value>
            </Setter>
            <Setter Property="toolkit:TransitionService.NavigationOutTransition">
                <Setter.Value>
                    <toolkit:NavigationOutTransition>
                        <toolkit:NavigationOutTransition.Backward>
                            <toolkit:TurnstileTransition Mode="BackwardOut"/>
                        </toolkit:NavigationOutTransition.Backward>
                        <toolkit:NavigationOutTransition.Forward>
                            <toolkit:TurnstileTransition Mode="ForwardOut"/>
                        </toolkit:NavigationOutTransition.Forward>
                    </toolkit:NavigationOutTransition>
                </Setter.Value>
            </Setter>
        </Style>
            
        // Other resources here...
    </Application.Resources>

This is defining a in and out transition that is a turnstile effect.  This is how almost all of the built in applications behave.

Modify the page

Add the transition to each page you want to use this behavior in the XAML.

<phone:PhoneApplicationPage 
    x:Class="YourApplication.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   // the rest of your xmlns stays the same, you need to add the toolkit and the style 

   // This reference loads the toolkit controls for this page
   xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"

    // This is named in the App.xaml (you can change it)
    Style="{StaticResource TransitionPageStyle}">

    // the rest of your page XAML stays the same....

/>

Do this for each page you want to use the transition effect.

Why do I have to hit back twice?

Phew, now to the reason I wrote this post…

In some situations you will notice that hitting back from your main page will navigate out, but the same page will appear rather than exiting the application. This will surely cause you to fail certification, and probably annoy a few users.

There are a couple different reasons why I have seen this happen.

There can be only one… RootFrame

The core of all the issues is that you can only have ONE RootFrame on your page.  If you are allocating a second frame for the transition and assigning it to the RootFrame you have two of them around. 

            RootFrame = new PhoneApplicationFrame();

            // This will make a SECOND Frame in your app
            RootFrame = new TransitionFrame();

This is the mistake I have seen online quite a bit.  People think they have to add a new TransitionFrame allocation and leave the original one in place.  You must delete the PhoneApplicationFrame() allocation line!

A more subtle version of this same bug is the one I ran into.  The Panorama project template creates a RootFrame for you in the App.xaml like this:

   <Application.RootVisual>
        <toolkit:PhoneApplicationFrame x:Name="RootFrame" Source="/MainPage.xaml"/>
    </Application.RootVisual>

This will cause a second allocation of a PhoneApplicationFrame!

If you remove that code from the xaml you will now safely be able to hit back and leave the application.

Comments are closed