WP7Contrib – Page Transitions and Navigation Service

I finally got around to updating the page transistions in wp7 contrib last week, its something that has been on my list for awhile. For a complete sample project check out the sample in the spikes folder where you can also find lots of other samples illustrating other tennants of the contrib.

The transitions used in the WP7C are based around the great work of Kevin Marshall who originally created the transitions, we like them becuase they are lighter on memory usage and slightly faster when compared to the page transitions found in the WP7 toolkit. Now that is not too say I dislike the transitions in the toolkit, I actually really like them mainly because we have the ability to define these transitions in Xaml and hopefully there will be some future design-time support in Blend where we could run these transitions. Xaml support for the transitions is definately on the vNext list for the WP7C as we believe its important for designers to able to change, apply and understand the different transitions that are available.

When comparing implementation details, the toolkit uses a custom Frame called a Transition Frame; and WP7C does this at a page level all the pages in your app have to sub class the Animated Base Page. Other differences include; the toolkit uses a Render Transform and WP7C uses Composite Transform; the WP7C uses the XamlReader.Load to setup the storyboards, however the toolkit has specific loose Xaml files that contain the storyboards.

So the new page transitions includes the different Rotate permutations for your page transitions, I also added in some new slide and fade transitions. You can play with these and all the other different transitions by downloading the sample app.

The other thing that I decided to add into the app was a very simple implementation of the WP7C navigation service. Page transitions and navigation are interconnected, when you navigate to a page you want to execute a transition between the current page and the new page, this is approapiate when going forwards or backwards. Normally we would wire up the WP7C Navigation Service in the bootstrapper of our app and use a DI framework to new this up. In order to keep everything super simple I am using the interface and manually newing up an instance, also note that I am not using a View Model this is simply to show the flexibility of the WP7C Navigation Service.

private WP7Contrib.Services.Navigation.INavigationService navigationService;

public MainPage()
{
        InitializeComponent();

       AnimationContext = LayoutRoot;
       this.navigationService = new WP7Contrib.Services.Navigation.ApplicationFrameNavigationService(
                                   ((App)Application.Current).RootFrame);
}

Notice how we grab the RootFrame and pass this in to the constructor of the WP7C Navigation Service the same code can be used in a bootstrapper. When using the WP7C transitions there is no requirement for us to change the base class of the frame in the App’s Initalize Phone App handler like we would do when using the toolkit.

private void InitializePhoneApplication()
{
    if (this.phoneApplicationInitialized)
    {
        return;
    }

    // Create the frame but don't set it as RootVisual yet; this allows the splash
    // screen to remain active until the application is ready to render.
    this.RootFrame = new TransitionFrame();
    this.RootFrame.Navigated += this.CompleteInitializePhoneApplication;

    // Handle navigation failures
    this.RootFrame.NavigationFailed += RootFrame_NavigationFailed;

    // Ensure we don't initialize again
    this.phoneApplicationInitialized = true;
}

Instead we need to hang all our pages from the Animated Base Page, pay close attention to; the constructor where we assign the Animated Context of our base page to the LayoutRoot of our page; and the overridden Get Animation where we are deciding which transitions to fire based on the Animation Type.

namespace PageTransition
{
    using System;

    using WP7Contrib.View.Transitions.Animation;

    public partial class Slide : AnimatedBasePage
    {
        public Slide()
        {
            InitializeComponent();

            AnimationContext = LayoutRoot;
        }

        protected override AnimatorHelperBase GetAnimation(AnimationType animationType, Uri toOrFrom)
        {
            if (animationType == AnimationType.NavigateForwardOut)
            {
                return new SlideLeftFadeOutAnimator { RootElement = LayoutRoot };
            }

            if (animationType == AnimationType.NavigateBackwardOut)
            {
                return new SlideRightFadeOutAnimator { RootElement = LayoutRoot };
            }

            if (animationType == AnimationType.NavigateForwardIn)
            {
                return new SlideLeftFadeInAnimator { RootElement = LayoutRoot };
            }

            return new SlideRightFadeInAnimator { RootElement = this.LayoutRoot };};
        }
    }
}

For completeness I have covered off the different permutations of Navigating forward or backward. The implemented page transitions have a corresponding Animator which makes it straightforward to implement the type of animation that you require. And that is everything you need in order to get page transitions working in your app. Once you have implemented the transitions you want then its a fairly simple task of using the WP7C Navigation Service to navigate to a page in your app.

private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (AnimationList.SelectedIndex != -1)
    {
        switch (AnimationList.SelectedIndex)
        {
            case 0:
                this.navigationService.Navigate(new Uri("/View/Turnstile.xaml", UriKind.Relative));
                break;

            case 1:
                this.navigationService.Navigate(new Uri("/View/TurnstileFeather.xaml", UriKind.Relative));
                break;

            case 2:
                this.navigationService.Navigate(new Uri("/View/Continuum.xaml", UriKind.Relative));
                break;

            case 3:
                //slide right
                this.navigationService.Navigate(new Uri("/View/SlideRight.xaml", UriKind.Relative));
                break;

        }
    }
}

And we are done!

Couple of things to watch out for when implementing the page transitions

  1. Make sure that you have the correct base url in you WMAppManifest.xml.
    It should look something like this

    <Tasks>
          <DefaultTask  Name ="_default" NavigationPage="View/MainPage.xaml"/>
        </Tasks>
    

    Even if you have a sub folder which contains your Views

  2. If you have already overriden the OnBackKeyPress handler remember to call the base implementation

If you have created transitions and happy to share or have ideas for ones you would like to see then please contact me.

Be Sociable, Share!

Tags: , , ,

3 Responses to “WP7Contrib – Page Transitions and Navigation Service”

  1. Did you manage to resolve your issues dude ?

    rich
  2. As you mentioned about using the base implementation for OnBackKeyPress event handler, I am needing to call the cancel handler to stop the page going back when there is a popup showing. However, when I do attempt to override the OnBackKeyPress handler, the page still goes back. Here is the code I am using…

    protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
    {
    base.OnBackKeyPress(e);

    e.Cancel = true;
    }

    Any ideas?

    Dan
  3. Hi Dan,

    I have not tried this, would you mind sending me a simple example of what you are trying and then i can take a look at the context and look into fixing up the issue in the Contrib. If you follow me on twitter then send me a tweet and we can talk more about the details

    rich

Leave a Reply