Zero To Phone Hero - Key points - part 1

I have just come back to Wellington after having spent a week travelling around and speaking at TechEd Australia and TechEd New Zealand...and of course CodeCamp in Auckland before TechEd.

Both TechEds were full of interesting people and interesting sessions. Not that I actually attended that many. But I assume they were interesting…

At both the aussie and kiwi conferences, me and Chris Auld showed off how to build an Azure backed Windows Phone 7 application in 60 minutes. And at both conferences, we promised to put up some blog posts around it. So here is my first one…one that talks about some of the key pieces that were shown. As well as some that weren’t shown…

There are a lot of “snippet programming” going on in my part of the demo, and I promise you, I hate that as much as everyone else. But, with the limited time, there isn’t room for me to stand around and type. It does however mean that some of the finer points in the demo do go by too fast or are possibly not even shown…

So in this post, I intend to cover some of the things in the demo that might be interesting. I will try to follow up with a couple of more posts about more things that might be interesting. If there is anything in particular you are wondering about, just drop me a line or add a comment about it, and I will try to get that up here as well…

Home page animation

One of the features I added to my application during the presentation is an animation that makes sure that the transition between the splash screen image and the home page is done using an animation instead of just an abrupt switch. I wanted to do this in a way that the design time experience would not be impacted at all. So I went for a dynamically created animation.

By overriding the OnNavigatedTo method, I get notified when the page has been navigated to. In this override, I add a new image control, showing the splash screen image, on top of the home page. I also plane project the existing content to go off the screen. I then animate the splash screen image so that it animates out in a nice way. As soon as that is done, I animate in the actual home page content. This is probably not the nicest way of doing it, but it works.

I do however want to make sure that the animation is only done the first time the page is loaded, and no when the user returns to it. And the easiest way to make sure that didn’t happen, was to place a bool property called IsInitiaized on the App class. This property is then set to true as soon as the animation has completed. I also make sure it is false before the animation is created.

And to make sure that everything works smoothly when coming back from having been tombstoned, I set the IsInitialized property to true in the Application_Activated method of the App class as well. This makes sure that even if the application has been “reset” due to a tombstoning (is that a correct word…? hmmm…), it will still not run the initial animation more than once…

HomePage.xaml.cs

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (((App)Application.Current).IsInitialized)
return;

BitmapImage bmp = new BitmapImage(new Uri("/SplashScreenImage.jpg", UriKind.Relative));
Image img = new Image();
img.Source = bmp;
LayoutRoot.Children.Add(img);
PlaneProjection imgProj = new PlaneProjection();
img.Projection = imgProj;
imgProj.CenterOfRotationX = 0;

PlaneProjection proj = new PlaneProjection();
panorama.Projection = proj;
proj.CenterOfRotationX = 0;
proj.RotationY = -100;

Storyboard sb = new Storyboard();
sb.Duration = TimeSpan.FromSeconds(1);

DoubleAnimation anim = new DoubleAnimation();
Storyboard.SetTarget(anim, imgProj);
Storyboard.SetTargetProperty(anim, new PropertyPath("RotationY"));
anim.To = -110;
anim.Duration = TimeSpan.FromSeconds(.5);
sb.Children.Add(anim);

anim = new DoubleAnimation();
Storyboard.SetTarget(anim, proj);
Storyboard.SetTargetProperty(anim, new PropertyPath("RotationY"));
anim.To = 0;
anim.BeginTime = TimeSpan.FromSeconds(.5);
anim.Duration = TimeSpan.FromSeconds(.5);
sb.Children.Add(anim);
sb.Completed += (s2, e2) =>
{
};

img.Loaded += (s2, e2) =>
{
Dispatcher.BeginInvoke(() =>
{
sb.Begin();
((App)Application.Current).IsInitialized = true;
});
};
}

App.xaml.cs

private void Application_Activated(object sender, ActivatedEventArgs e)
{
IsInitialized = true;
}

public bool IsInitialized
{
get;
set;
}

 

Page transition animations

During the presentation, I mentioned that I didn’t like the fact that the transitions between pages where non-existent. They just flip from one page to another. So to solve this, I replaced the existing PhoneApplicationFrame with an AnimatingPhoneApplicationFrame. I also mentioned that this was a control that I had built myself. I did however not show you how it was implemented… There are two parts to this that are “interesting”.

First off, I’ve heard some comments that you can’t change the frame anymore since the last refresh of the tools. This isn’t true… In the previous release, the root visual was set explicitly in the App.xaml file, making it very easy to find and replace. In the latest refresh however, this has been moved to the code behind of the App.xaml. It has also been put into a region that is by default collapsed. But if you just go in there and have a look, you will find a row of code that says RootFrame = new PhoneApplicationFrame();. In my presentation I just replaced that with an AnimatingPhoneApplicationFrame.

The second interesting part of this thing is obviously the implementation of the AnimatingPhoneApplicationFrame. The implementation of the frame is actually very simple. All I have done is that I have inherited from PhoneApplicationFrame, and changed the template for it. I could obviously have just modified the template of the existing frame, but doing it this way makes it a little bit more reusable. So the code for the AnimatingPhoneApplicationFrame looks like this

Code

public class AnimatingPhoneApplicationFrame : PhoneApplicationFrame
{
public AnimatingPhoneApplicationFrame()
{
DefaultStyleKey = typeof(AnimatingPhoneApplicationFrame);
}
}

XAML

<Style TargetType="local:AnimatingPhoneApplicationFrame">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:AnimatingPhoneApplicationFrame">
<local:TransitioningContentControl Content="{TemplateBinding Content}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

As you can see, the biggest change is the template. And the template is simple. But it does include another control that I have custom built. It doesn’t support changing animations and so on. I just wanted a VERY simple control that would add a transition to each of the page changes…

So let’s look at how it has been implemented. And I would suggest starting at the template end… And the template looks like this

<Style TargetType="local:TransitioningContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TransitioningContentControl">
<Grid x:Name="LayoutRoot">
<ContentPresenter x:Name="ContentSite" Content="">
<ContentPresenter.Projection>
<PlaneProjection CenterOfRotationX="0" />
</ContentPresenter.Projection>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

As you can see, it isn’t complicated. I would definitely suggest building something more flexible…but for now this works for me.

Bu where is the animation? Well…in the code. Once again…possibly not the best solution, but as I mentioned in the presentation, we built this application in a couple of weekend sessions. So there wasn’t really a lot of time to build nice and reusable controls. Only enough to build something that worked…

So the code for the control looks like this

public class TransitioningContentControl : ContentControl
{
public TransitioningContentControl()
{
DefaultStyleKey = typeof(TransitioningContentControl);
}

public override void OnApplyTemplate()
{
base.OnApplyTemplate();

ContentSite = GetTemplateChild("ContentSite") as ContentPresenter;
ContentSite.Content = Content;

AnimateOut = new Storyboard();
DoubleAnimation animation = new DoubleAnimation();
animation.To = -120;
animation.Duration = TimeSpan.FromSeconds(.5);
Storyboard.SetTarget(animation, ContentSite.Projection);
Storyboard.SetTargetProperty(animation, new PropertyPath("RotationY"));
AnimateOut.Children.Add(animation);
AnimateOut.Completed += (s, e) =>
{
Debug.WriteLine("AnimateOut.Completed");
ContentSite.Content = Content;
AnimateIn.Begin();
};

AnimateIn = new Storyboard();
animation = new DoubleAnimation();
animation.To = 0;
animation.Duration = TimeSpan.FromSeconds(.5);
Storyboard.SetTarget(animation, ContentSite.Projection);
Storyboard.SetTargetProperty(animation, new PropertyPath("RotationY"));
AnimateIn.Children.Add(animation);
}
protected override void OnContentChanged(object oldContent, object newContent)
{
StartTransition(oldContent, newContent);
}
private void StartTransition(object oldContent, object newContent)
{
if (AnimateOut != null)
{
Dispatcher.BeginInvoke(() =>
{
Debug.WriteLine("AnimateOut.Begin");
AnimateOut.Begin();
});
}
}

private ContentPresenter ContentSite { get; set; }
private Storyboard AnimateOut { get; set; }
private Storyboard AnimateIn { get; set; }
}

As you can see…it isn’t that complicated. It handles overrides the OnContentChanged method to start an animation that animates “out” the existing content, then changes the content and starts an animation that animates it “in”…

And yes, is looks as if there is more code in there than that…but that is just the storyboard creation…

Well…that’s it for now. I will try to get some more code and explanations up here for you as soon as I possibly can. The plan is to go through the different “services” that was used during the demo and explain how and why they are needed…

Cheers for now…

Comments (2) -

Thank You so much for the post.

In the HomePageAnimation part, you mentioned the variable 'panorama' in the HomePage.xaml.cs code. I think you just missed to define this varible.
Kindly, update the code base.

Thank You!

Fortunately, I got the information about the Panorama, that it is the silverlight control.
I am sorry for missunderstanding. However, I am new to WP7 development as well as for Silverlight.
Today, I got information about the panorama in the following blog:
http://windowsteamblog.com/windows_phone/b/wpdev/

Pingbacks and trackbacks (1)+

Comments are closed