Custom Per-Page Transitions for Windows Phone 7

Sign in to queue


Continuing our previous explorations of the TransitioningContentControl (here and here – all WinPhone content here), we will now take a look at how we can extend the TCC to allow transitions to be defined on a per-page basis. Simply put, we would like to have a default transition for all pages, and to provide a list of custom transitions to use on a page-by-page basis. In addition to this article, you can watch a screencast of making these changes, and source is linked at the end of the article.

Our first step is creating a simple class that will be used to hold Page-to-Transition mappings. That class is shown below:

  1. namespace System.Windows.Controls
  2. {
  3.      public class PageTransitionMapping
  4.      {
  5.           public string Page { get; set; }
  6.           public string Transition { get; set; }
  7.      }
  8. }

I added this class to the TCC folder from the previous screencast (download here). Notice that I changed the namespace to match the TCC’s namespace.

Next, the TCC is modified, allowing us to provide Page-To-Transition mappings via the App.xaml file. See below:

  1. public class TransitioningContentControl : ContentControl
  2. {
  4. private List<PageTransitionMapping> _mappings = new List<PageTransitionMapping>();
  5. public List<PageTransitionMapping> PageTransitionMappings { get { return _mappings; } }
  6.   …

The _mappings field stores a List<> of PageTransitionMapping objects. These mapping objects are created by accessing the PageTransitionMappings property via App.xaml as shown below

  1. <phoneNavigation:PhoneApplicationFrame x:Name="RootFrame" Source="/MainPage.xaml">
  2. <phoneNavigation:PhoneApplicationFrame.Template>
  3. <ControlTemplate>
  4. <layout:TransitioningContentControl Content="{TemplateBinding Content}" Style="{StaticResource TransitioningStyle}">
  5. <layout:TransitioningContentControl.PageTransitionMappings>
  6. <layout:PageTransitionMapping Page="AprilCTP.Views.Favorites.Default" Transition="SwingTransition" />
  7. </layout:TransitioningContentControl.PageTransitionMappings>
  8. </layout:TransitioningContentControl>
  9. </ControlTemplate>
  10. </phoneNavigation:PhoneApplicationFrame.Template>

In this example, the Default.xaml page in the Views/Favorites folder has been mapped to use the SwingTransition. Just like before, all of the transitions used by the TCCC must be in the TCC’s Style definition (specifically, in the ControlTemplate’s VisualStateManager).

The next to last step is to update the way the TCC applies transitions to pages as they are displayed. To do this, we update the TCC’s StartTransition() method as shown below:

  1. private void StartTransition(object oldContent, object newContent)
  2. {
  3. // both presenters must be available, otherwise a transition is useless.
  4. if (CurrentContentPresentationSite != null && PreviousContentPresentationSite != null)
  5. {
  6. PageTransitionMapping transitionMapping = null;
  7. var newPage = newContent as PhoneApplicationPage;
  9. if (newPage != null)
  10. {
  11. string pageType = newPage.GetType().ToString();
  12. transitionMapping = (from m in this.PageTransitionMappings where m.Page == pageType select m).SingleOrDefault();
  13. }
  17. // and start a new transition
  18. if (!IsTransitioning || RestartTransitionOnContentChange)
  19. {
  20. IsTransitioning = true;
  22. if (transitionMapping != null)
  23. {
  24. Transition = transitionMapping.Transition;
  25. }
  26. else
  27. Transition = _standardTransition;
  29. CurrentContentPresentationSite.Content = newContent;
  30. PreviousContentPresentationSite.Content = oldContent;
  31. VisualStateManager.GoToState(this, NormalState, false);
  32. VisualStateManager.GoToState(this, Transition, true);
  33. }
  34. }
  35. }

There are a couple of important points. First, the CurrentContextPresentionSite.Content = and the PreviousContentPresentationState.Content = lines of code have been moved a bit from where they appeared in the original code. Second, there is no real error handling for cases where you enter the wrong name for your custom transition inside the App.xaml mapping. This is more “proof of concept” code than production ready code. The TCC has a GetStoryboard method that you can use to make sure the transition is available it is just a matter of where you want to detect that and how you want to handle it in the case that a transition does not exist (falling back to the default transition is probably easiest).

The last thing we have to do is set the value for _standardTransition. We will set its value in the OnApplyTemplate() method inside the TCC. This method gets called one time when the TCC is first created and the template is applied. We will add the declaration for _standardTransition immediately before the method (stick it where ever you like):

  1. private string _standardTransition;
  2. /// <summary>
  3. /// Builds the visual tree for the TransitioningContentControl control
  4. /// when a new template is applied.
  5. /// </summary>
  6. public override void OnApplyTemplate()

The OnApplyTemplate discovers the value of the TCC Transition property that was set in the Style in the App.xaml file. Setting _standardTransition to this value lets us use it whenever there is not a custom page transition defined. Update the OnApplyTemplate() method as shown:

  1. ^^^^ REST OF METHOD ^^^^
  2. _standardTransition = Transition;
  3. VisualStateManager.GoToState(this, NormalState, false);
  4. }


I have included the source for a working solution here.



Download this episode

The Discussion

Add Your 2 Cents