2012 Illinois Technology Association - CityLights Finalist

BLOGS

MPS Partners provides functional and technical expertise and insights into business process management trends and Microsoft technologies.

Contact Us
HOT JOBS
Interested in reviewing our current job openings or submitting a resume?
CLICK HERE
Home » Blog » .NET Development » Using the TransitionFrame and Fast Resume together

Using the TransitionFrame and Fast Resume together

Introduction

When using shipping versions of the Windows Phone Toolkit’s TransitionFrame together with the new  Windows Phone 8 fast app resume feature, application transitions get confused.

The Windows Phone Toolkit gives us easy intra-app transitions. Windows Phone 8 includes an easy-to-implement fast resume feature along with its own ‘application suspending’ and ‘application resuming’ transitions which are similar to full-page Turnstile animations. Using both of these already-written-and-tested features makes our development lives much easier, so what can we do to get them working together?

Let’s review how each of these components work on their own.

TransitionFrame

Before we get to transitions, let’s check out the base class implementation. The process for navigating between pages within a PhoneApplicationFrame is as follows:

1.      Frame.Navigate(NewUri) is called

2.      Frame.Navigating event is fired

a.       NavigatingCancelEventArgs.Uri: NewUri

b.      NavigatingCancelEventArgs.NavigationMode: NavigationMode.New

c.       Frame.Source: OldUri

3.      Unless Canceled, Frame.Navigated event is fired

a.       NavigationEventArgs.Uri: NewUri

b.      NavigationEventArgs.NavigationMode: NavigationMode.New

The TransitionFrame component lets us assign TransitionIn and TransitionOut transitions for both back and forward navigation. These are executed by the TransitionFrame via the  Frame.Navigating event.

The TransitionFrame augments the PhoneApplicationFrame as such:

1.      Frame.Navigate(NewUri) is called

2.      Frame.Navigating event is fired

a.       TransitionFrame starts playing transition but does not block;

3.      Unless Canceled, Frame.Navigated event is fired

a.       TransitionFrame is not equipped to handle Canceled Navigations.

Fast App Resume

Before fast app resume, Windows Phone would just fire PhoneApplicationService.Launching, usually sending the user into the app as if it had just been opened, unless complicated custom resume functionality had been implemented.

With fast app resume, we just add an ActiviationPolicy to our WMAppManifest.xml file…

<DefaultTask Name=_default ActivationPolicy=Resume />

And we get pretty easy, free resume logic.

On suspend, Windows Phone will store the current Uri of the root frame (referred to later as SuspendUri).

On resume, Windows Phone will:

​1.      Fire the Frame.Navigating event

a.       NavigatingCancelEventArgs.Uri: SuspendUri

b.      NavigatingCancelEventArgs.NavigationMode: NavigationMode.Reset

c.       Frame.Source: SuspendUri

2.      Fire the Frame.Navigated event

a.       NavigationEventArgs.Uri: SuspendUri

b.      NavigationEventArgs.NavigationMode: NavigationMode.Reset

3.      Fire the Frame.Navigated event a second time

a.       NavigationEventArgs.Uri: SuspendUri

b.      NavigationEventArgs.NavigationMode: NavigationMode.Refresh

Perfect, right?

The Problem

All this ‘free’ functionality from any major player within the mobile space, especially one trying to catch up to the pack. As an application developer, I’ll take any shortcuts I can get for my app to have a great native user experience. What do we get for trying to have all our cake and eat it too? Unfortunately, Bad news. The TransitionFrame and fast app resume have clearly been written without any consideration for the other and obviously weren’t tested together. I will cut TransitionFrame some slack as it is somewhat old. So all fingers point to fast app resume.

Let’s review the combined chronology of TransitionFrame and fast app resume:

1.      (Our application is in foreground at SuspendUri and user presses Windows button on phone)

2.      Concurrently:

a.       Windows Phone 8 built-in full-page out-of-process TransitionOut Forward Turnstile transition on application being suspended

b.      Our application:

i.      Frame.Navigating fired: NavigationMode.New from SuspendUri to app://external/ (our application is suspended before TransitionFrame gets to start the transition associated with this event)

ii.      Frame.Navigated fired: NavigationMode.New to app://external/

3.      (User selects suspended application from home screen or all applications list)

4.      Windows Phone 8 built-in full-page out-of-process TransitionIn Forward Turnstile transition on application being resumed

5.    TransitionFrame starts playing transition for (2.b.i)

6.      Frame.Navigating fired: NavigationMode.Reset from SuspendUri to SuspendUri

7.      TransitionFrame starts playing transition into OldUri

8.      Frame.Navigated fired: NavigationMode.Reset to SuspendUri

9.      Frame.Navigated fired: NavigationMode.Refresh to SuspendUri

Which to the user looks like:

Video of the Problem

Not good.

The Solution

We need a way to prevent the TransitionFrame from playing these extra transitions.

My first thought: There must be some property or event I can hook into and attempt to cancel or bypass the animations. This was a quick no-go. TransitionFrame is functionally bare. How about fast app resume? Same situation: no flexibility at all.

My second thought: Subclass TransitionFrame! This quickly leads to a brick wall: practically everything is internal or private, especially the stuff we care about.

My third thought: To my surprise, TransitionFrame is actually open source! We can grab a copy and make some modifications!

After you copy the file in, change the namespace, and compile we are dealt our first hurdle: OnBeginTransition and OnEndTransition are both private. Reflection to the rescue!

Make the following code substitutions:

//navigationTransition.OnBeginTransition();               

MethodInfo dynMethod
= navigationTransition.GetType().GetMethod(
“OnBeginTransition”,

BindingFlags.NonPublic | BindingFlags.Instance);

dynMethod.Invoke(navigationTransition,
new object[] {
});

//navigationTransition.OnEndTransition();

MethodInfo dynMethod
= navigationTransition.GetType().GetMethod(
“OnEndTransition”,

BindingFlags.NonPublic | BindingFlags.Instance);

dynMethod.Invoke(navigationTransition,
new object[] {
});

Let’s now set App.xaml.cs to use our new TransitionFrame inside InitializePhoneApplication.

It builds! But does it run? Yes, with a huge caveat: the transitions don’t play. It turns out we also need a style from Themes\Generic.xml:

<Style TargetType=”transition:TransitionFrame”>

    <Setter Property=”Background” Value=

“{StaticResource PhoneBackgroundBrush}”/>

    <Setter Property=”BorderBrush” Value=”Transparent”/>

    <Setter Property=”BorderThickness” Value=”0″/>

    <Setter Property=”HorizontalContentAlignment” Value=”Stretch”/>

    <Setter Property=”VerticalContentAlignment” Value=”Stretch”/>

    <Setter Property=”Template”>

   
    
<Setter.Value>

   
        
<ControlTemplate TargetType=”transition:TransitionFrame”>

   
            
<Border

   
                
x:Name=”ClientArea”

                 
 
 Background=”{TemplateBinding Background}”

   
               
 BorderBrush=”{TemplateBindingBorderBrush}”

   
               
 BorderThickness=”{TemplateBindingBorderThickness}”

   
               
 Margin=”{TemplateBinding Margin}”>

   
                
<Grid>

   
                   
<ContentPresenter

   
                       
 x:Name=”FirstContentPresenter”

   
                       
 HorizontalAlignment=

“{TemplateBindingHorizontalContentAlignment}”

   
                       
 VerticalAlignment=

“{TemplateBindingVerticalContentAlignment}”/>

   
                    
<ContentPresenter

   
                       
 x:Name=”SecondContentPresenter”

   
                       
 HorizontalAlignment=

“{TemplateBindingHorizontalContentAlignment}”

   
                       
 VerticalAlignment=

“{TemplateBindingVerticalContentAlignment}”/>

   
                
</Grid>

   
            
</Border>

   
        
</ControlTemplate>

   
    
</Setter.Value>

  
 
</Setter>

</Style>

I added a copy of this to my ApplicationStyleDictionary.xaml.

Okay, now we can move onto actually fixing the problem. Because Windows Phone 8 plays its own transitions in and out of our application on resume and suspend respectively, the transitions our application plays in and out of the active frame are redundant; we need to prevent one pair from playing. Windows Phone 8 gives us no control over the animations it’s playing, so that leaves our own transitions to deal with.

If we look back at our review of the combined chronology of TransitionFrame and fast app resume, we can see we have no choice but to keep (2.a) and (4), and we want to prevent (5) and (7). Our next step is to figure out where TransitionFrame is starting transitions so that we may prevent the ones in question from occurring.

The only time the TransitionFrame starts transitions is within the Frame.Navigating event handler private void OnNavigating(objectsender, NavigatingCancelEventArgs e) so let’s start investigating there. If we look back at our chronology again, we can figure out what sets the OnNavigating invocations we are interested in apart from the others. The cause of transition (5) is the invocation (2.b.i) and the cause for transition (7) is invocation (6). Invocation (2.b.i) is unique in that the NavigatingCancelEventArgs.Uri is equal to app://external/ and (6) is unique in that NavigatingCancelEventArgs.NavigationMode is equal to NavigationMode.Reset. Now that we have our two special conditions, let’s skip execution of OnNavigating when they are true:

private void
OnNavigating(object sender, NavigatingCancelEventArgs e)

{

    if (e.NavigationMode == NavigationMode.Reset
|| e.Uri.OriginalString == “app://external/”)

        return;

   

}

Problem solved? Let’s build, run, and test the solution.

Video of the Solution

Success!

Conclusion

After coercing a copy of the open-source TransitionFrame class into our project and making a single minor change, we can now use fast app resume with our transitions intact!

Implications

I’m guessing distributing our modified copy of TransitionFrame.cs and Generic.xaml requires us to also include some mention of the fact that part of our application is Copyright Microsoft under the terms of the Microsoft Public License (Ms-PL).

This entry was posted in .NET Development and tagged , , . Bookmark the permalink.

One Response to Using the TransitionFrame and Fast Resume together

  1. Amelia Lewis says:

    Great details in this post!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Current day month ye@r *

 
View By Author
  • View By Category
View By Date
Part Of SPR COMPANIES
© 2014 SPR Companies. All rights reserved. About | Capabilities | Products | Solutions | Clients | Events & Resources | Careers | Site Map | Legal/Privacy