Overview

The November release of Silverlight for Windows Phone Toolkit has animations that mimic some typical Windows Phone animations that you see for arbitrary visual objects. These animations are called transitions.

ITransition is an interface that mimicks the Storyboard interface. ITransition exists so things like bitmap caching and disabling hit test visibility can be done for you behind the scenes. Were Storyboard not sealed, ITransition would not exist because we would subclass Storyboard instead to do these things. Your own ITransition implementations can do whatever you want, although caching and disabling hit test visibility are recommended for better performance and usability.

TransitionElement is an abstract class that has the abstract method GetTransition, which takes UIElements and gives ITransitions for them. There are five built-in TransitionElements: RollTransition, RotateTransition, SlideTransition, SwivelTransition, and TurnstileTransition. All of them except for RollTransition actually represent families of similar transitions and provide a Mode property that lets you select which specific transition you want. There are enums for each transition family to choose a mode: RotateTransitionMode, SlideTransitionMode, SwivelTransitionMode, and TurnstileTransitionMode.

NavigationTransition has Backward and Forward properties of type TransitionElement that lets you specify the Page transitions to use for backward and forward Page navigations. NavigationInTransition and NavigationOutTransition are trivial subclasses of NavigationTransition.

TransitionService is a static class that has a NavigationInTransition property of type NavigationInTransition and a NavigationOutTransition property of type NavigationOutTransition that let you specify backward and forward transitions for in and out Page navigations. You can set TransitionService.NavigationInTransition and TransitionService.NavigationOutTransition on any UIElement, but out of the box it's only useful to set them on Pages because only Pages navigate.

Here's how to think of the four Page navigation transitions:


Here's what it all looks like in XAML:

<Page>

    <toolkit:TransitionService.NavigationInTransition>

        <toolkit:NavigationInTransition>

            <toolkit:NavigationInTransition.Backward>

                <toolkit:TurnstileTransition Mode="BackwardIn"/>

            </toolkit:NavigationInTransition.Backward>

            <toolkit:NavigationInTransition.Forward>

                <toolkit:TurnstileTransition Mode="ForwardIn"/>

            </toolkit:NavigationInTransition.Forward>

        </toolkit:NavigationInTransition>

    </toolkit:TransitionService.NavigationInTransition>

    <toolkit:TransitionService.NavigationOutTransition>

        <toolkit:NavigationOutTransition>

            <toolkit:NavigationOutTransition.Backward>

                <toolkit:TurnstileTransition Mode="BackwardOut"/>

            </toolkit:NavigationOutTransition.Backward>

            <toolkit:NavigationOutTransition.Forward>

                <toolkit:TurnstileTransition Mode="ForwardOut"/>

            </toolkit:NavigationOutTransition.Forward>

        </toolkit:NavigationOutTransition>

    </toolkit:TransitionService.NavigationOutTransition>

</Page>

(BackwardIn, ForwardIn, BackwardOut, and ForwardOut are values of TurnstileTransitionMode.)

Here's what it all looks like in code:

NavigationInTransition navigationInTransition = new NavigationInTransition

{

Backward = new TurnstileTransition { Mode = TurnstileTransitionMode.BackwardIn },

Forward = new TurnstileTransition { Mode = TurnstileTransitionMode.ForwardIn }

};

NavigationOutTransition navigationOutTransition = new NavigationOutTransition()

{

Backward = new TurnstileTransition { Mode = TurnstileTransitionMode.BackwardOut },

Forward = new TurnstileTransition { Mode = TurnstileTransitionMode.ForwardOut }

};

PhoneApplicationPage phoneApplicationPage = ...

TransitionService.SetNavigationInTransition(phoneApplicationPage, navigationInTransition);

TransitionService.SetNavigationOutTransition(phoneApplicationPage, navigationOutTransition);

Using them anywhere

Since TransitionElement.GetTransition takes a UIElement, you can use the built-in transition families to make transitions for arbitrary UIElements. Here's how to slide a Button:

Button button = ...

SlideTransition slideTransition = new SlideTransition { Mode = SlideTransitionMode.SlideUpFadeIn };

ITransition transition = slideTransition.GetTransition(button);

transition.Completed += delegate { transition.Stop(); };

transition.Begin();

Disabling navigation transitions

If you want to disable navigation transitions for a Page, set TransitionService.NavigationInTransition and TransitionService.NavigationOutTransition to null on the Page. If you want to restore those values, just store them beforehand and then set them again.

PhoneApplicationFrame frame = (PhoneApplicationFrame)Application.Current.RootVisual;

PhoneApplicationPage page = (PhoneApplicationPage)frame.Content;

// Save the transitions

NavigationInTransition oldIn = TransitionService.GetNavigationInTransition(page);

NavigationOutTransition oldOut = TransitionService.GetNavigationOutTransition(page);

// Clear the transitions

TransitionService.SetNavigationInTransition(page, null);

TransitionService.SetNavigationOutTransition(page, null);

// Restore the transitions

TransitionService.SetNavigationInTransition(page, oldIn);

TransitionService.SetNavigationOutTransition(page, oldOut);

Customizing

There are two ways to customize transitions: subclassing TransitionElement or making a reusable Storyboard transition.

Here's how to make your own TransitionElement for your own Storyboard:

class Transition : ITransition

{

    Storyboard _storyboard;

    public Transition(Storyboard storyboard)

    {

        _storyboard = storyboard;

    }

    public void Begin()

    {

        _storyboard.Begin();

    }

    ...

}

class MyTransition : TransitionElement

{

    public ITransition GetTransition(UIElement element)

    {

        MyStoryboard myStoryboard = new MyStoryboard();

        Storyboard.SetTarget(myStoryboard, element);

        return new Transition(myStoryboard);

    }

}

<Page>

    <toolkit:TransitionService.NavigationInTransition>

        <toolit:NavigationInTransition>

            <toolkit:NavigationInTransition.Forward>

                <local:MyTransition/>

            </toolkit:NavigationInTransition.Forward>

        </toolit:NavigationInTransition>

    </toolkit:TransitionService.NavigationInTransition>

</Page>

Here's how to make a reusable Storyboard transition:

StoryboardTransition : TransitionElement

{

    public static DP StoryboardProperty ...;

    ...

}

<Page>

  <Page.Resources>

    <Storyboard x:Key=”MyStoryboard” .../>

  </Page.Resources>

  <toolkit:TransitionService.NavigationInTransition>

    <toolit:NavigationInTransition>

      <toolkit:NavigationInTransition.Forward>

        <local:StoryboardTransition Storyboard=”{StaticResource MyStoryboard}”/>

      <toolkit:NavigationInTransition.Forward>

    <toolit:NavigationInTransition>

  <toolkit:TransitionService.NavigationInTransition>

</Page>

Don't forget

For Page navigation transitions to work automatically, you have to set your application's RootFrame property to an instance of TransitionFrame in App.InitializePhoneApplication, typically found in App.xaml.cs:

RootFrame = new TransitionFrame();