During the past couple weeks, I had the opportunity to work with a client that was interested in putting together an eye-catching web site that would be purely informational in nature. Knowing that Silverlight 3 has a new project template for navigation, I started poking around the template to see if this could be used. The client wanted to have a certain “Wow” factor to the web site to separate it out from others in his line of work, so I mentioned that Silverlight is a great technology to look at regarding rich experiences within the UI. Taking into account the business need for a unique site but still making it informational and professional, I decided to use the new Navigation template and add some page transition animations as well as some custom navigation buttons and other graphics. This post will cover the technique I used to implement custom page transitions in this client’s web site.
As I usually do, I researched various blog posts, sites and books to determine a good way to modify the navigation template for custom page transitions. I found a couple sites that helped me tremendously in understanding what controls I would have to implement and modify. This blog posting was probably the most helpful. It gives instruction on how to replace the Content Presenter Control in the navigation frame with a Transitioning Content Control, new in Silverlight 3. This new control allows you to use 4 built in transition effects if one of them meets your needs, but you also can modify the template to create your own, which is what I did. Jesse Liberty has a great video about the Transitioning Content Control available in the Learn section of the Silverlight.net web site.
So, in the end, we decided to create a site with 5 different “pages” for the user to navigate through. The transition we thought would give enough impact would be a rotating transition, where the page seems like it’s rotating around an axis giving it a 3D type look. The current page would rotate half way, then it would be replaced by the new page and then rotate back. Obviously, this transition is not one of the 4 built in for the control, so I’d have to modify the template to create the effect. The tools I used to do this were Visual Studio 2008, Expression Blend 3 + SketchFlow (trial version), Silverlight 3 tools and the Silverlight 3 Toolkit, all available here.
The following steps will describe the technique used to create this custom page transition.
1) Open Visual Studio 2008 and create a new Silverlight Navigation Application project. When asked to create a web project, click OK.
2) The site should open to the MainPage.xaml page. If not, open the MainPage.xaml file and find the tag <navigation:Frame…. This is the control we are going to modify to implement the custom transition.
1: <Border x:Name="ContentBorder" Style="{StaticResource ContentBorderStyle}">
2:
3: <navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}"
4: Source="/Home" Navigated="ContentFrame_Navigated" NavigationFailed="ContentFrame_NavigationFailed">
5: <navigation:Frame.UriMapper>
6: <uriMapper:UriMapper>
7: <uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>
8: <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>
9: </uriMapper:UriMapper>
10: </navigation:Frame.UriMapper>
11: </navigation:Frame>
12: </Border>
3) In the Solution Explorer, right click on MainPage.xaml and select “Open in Expression Blend…”. If not already viewable, click on the Objects and Timeline tab to view the controls on the MainPage.xaml page, as shown below.
3) You’ll notice that the page contains many controls. The one we’re concerned about is the ContentFrame control. Under [UserControl] –> ContentBorder there’s a frame control called ContentFrame. Right click on this control, hover over Edit Template and select Edit a Copy…
4) A box called Create ControlTemplate Resource will appear. In the Name(Key) box, type CustomTransitioningNavFrame. In the section labeled Define In, select the radio button next to Resource Dictionary. To the right of the drop down box, click the New button.
5) Clicking the New button should bring up another box named New Item. In the Name box, replace the contents with CustomControls.xaml and click OK. What we’re doing is creating the file that will hold the styles and animation storyboards for a new control based upon the existing control. This file can also be used in the future to hold any styles and storyboards for additional controls that are customized within the site. You do have the option of storing this code in the existing page as well. I decided to do it this way because I believe it’s cleaner and gives you the opportunity to used the code in additional pages throughout the site.
You’ll now notice that the Resource dictionary drop down says CustomControls.xaml. If not, pull down the drop down and select it. If it’s not there, repeat step four to create the file. When finished, click OK.
6) When you click OK, you’ll be taken back to the Expression UI and will notice there is a black rectangle with “Frame” in the upper left corner (or somewhere within the rectangle). In the Objects and Timelines tab, you should see ControlTemplate –> [Border] –> [ContentPresenter]. The Border and the ContentPresenter make up the structure of the navigation frame. What we want to do now to implement a page transition is to replace the ContentPresenter control with a TransitioningContentPresenter control. This control is available in the System.Windows.Controls.Layout.Toolkit.dll assembly.
Right click on the [ContentPresenter] control in the Objects and Timelines tab and click Delete. Click once on the [Border] control to highlight it. In the rectangle, you should see an arrow pointing down and to the right. Click and drag this arrow all the way out to the border of the rectangle.
7) Click the [Border] control once to highlight it. To the left of the Expression Blend window, you should see the toolbox with the various controls available. On the bottom of the tool box, you should see a button with two arrow-like shapes pointing to the right. If you hover over this button, it should say Assets. Click on the Assets button. You’ll now see a menu-type list on the left side of the box that opens, as well as control names on the right. At the bottom of the list on the left, you’ll see an option called Locations, with an arrow to the left of it. Click this arrow. You’ll then see (eventually – it may take a while to load them) a list of DLL names. This list of assemblies will load and eventually you should see an assembly named System.Windows.Controls.Layout.Toolkit.dll. Once you click on this assembly, a group of controls will appear to the right. One of them should be the Transitioning Content Presenter control. Double click this control – you should then see the control’s icon appear under the Assets button. Double click on the icon to insert the control under the Border control in its default size, which should stretch the control to the dimensions of the border.
8) So, at this point we’ve replaced the ContentPresenter control with the TransitioningContentPresenter control. If you didn’t want to create a custom transition and wanted to use one of the built in transitions of the control, you could stop here. All you’d have to do is modify the xaml of the control and set the Transition attribute of the control to one of the four existing transitions (which are DefaultTransition, Normal, UpTransition and DownTransition) and set the Content attribute to {TemplateBinding Content}. But, we wanted another type of transition, so now we must edit the template of the TransitioningContentPresenter to create a new transition and set some values so that it works the way we want.
Right click the [TransitioningContentControl] and select Edit Template –> Edit a copy…. In the Create Style Resource box that opens, under Name(Key), type CustomTransitioningContentCtrl. Under the Define In section, select the radio button next to Resource dictionary and in the drop down box, select CustomControls. This will ensure that the styles and storyboards we’re going to create will be kept in this file. Click OK.
9) You’ll now notice that under the Objects and Timelines tab under the Template heading, you have [Border] –> [Grid] –> PreviousContentPresentationSite and CurrentContentPresentationSite. The Previous and Current controls are Content Presenter controls that make up the Transitioning Content Presentation control. These controls represent the content (or “page”, in this case) that was being displayed previous to the transition being implemented and the content that will be displayed after the transition is complete. These two content presenters are the key players in the Transitioning Content Control and will be what the animations and storyboards will be manipulating during the transitions.
We have to make a couple changes to these two content presenters to get them to act the way we want them to. These changes need to be done the same way to both content presenters. First, we have to resize the Grid and center both presenters in the Grid. Second, we have to set the center points of each presenter so that the will rotate around the middle of themselves when we implement the transition.
For the first change, click on the Grid control under Objects and Timelines. In the design window, drag the lower right corner of the grid to lower right corner of the black rectangle. Doing this will statically set the dimensions of the grid. Now, under Objects and Timelines, click on the PreviousContentPresentationSite control. On the right side of Expression Blend, you should see the Properties tab. If Layouts is not expanded, go ahead and expand it. At this point, you’ll notice that there is an orange border around the Horizontal Alignment and Vertical Alignment options. These borders indicate that these settings are fixed in the control, but we can manipulate them by changing it to a local value. To do this, click within the Horizontal Alignment border. A menu will pop up and you should see the option Convert to Local Value. Click that option and the orange border will disappear. Do the same for the Vertical Alignment option. Go ahead and click the Center option in both the Vertical and Horizontal sections (should be the second one from the left). The content will now appear in the center of the grid for both the Previous and Current content presenters.
10) The next step is to set the center point of each Content Presenter. To do this, select the PreviousContentPresentationSite content presenter by clicking it once in the Objects and Timelines tab. Go to the Properties tab to the right of the designer and expand the Transform section. Within the Transform section, you’ll see Render Transform and Projection areas. Under Projection, there are 4 tabs. The second tab should be Center of Rotation. Click on this tab and you’ll see boxes with X, Y and Z next to them, which are probably filled with 0s. Change the 0s to 0.5 for all three boxes. Doing this will set the center of rotation directly in the middle of the content presenter control you’re working with. Repeat these steps for the CurrentContentPresentationSite content presenter.
11) We still have to make sure that our content presenters show the content of the pages we want to display. To do this, select the PreviousContentPresentationSite content presenter by clicking it once in the Objects and Timelines tab. Again in the Properties section, find the Common Properties area. Within this area, there’s a Content box which has a small white square to the right of it. Click on this square and you’ll see a menu come up called Content with an option for Template Binding. Hover over this option and another menu will come up. Find the Content option and click it. This tells the control to look to the Content template for the content of the control. Do the same thing with the CurrentContentPresentationSite content presenter.
We also have to set the navigation frame control that contains the Transitioning Content Control to get its content from the same template binding setting. To do this, close the CustomControls.xaml file and return to the MainPage.xaml file. Right click again on the ContentFrame control under the ContentBorder control and hover over Edit Template… and select Edit Current. You’ll again see the [TransitioningContentControl] under the [Border] control (look familiar?). Follow the steps above to change the content to read from the TemplateBinding content setting for this control. When finished, right click on the [TransitioningContentControl] control, hover over Edit Template… and select Edit Current to go back to the contents of the Transitioning Content Control.
12) We have now prepared our Transitioning Content Control and its parts for the animation we want. The next thing to do is to create the visual state for the effect we want. Showing exactly how to do this in Blend using the Timeline would take a lot of time, so I think it’s better just to give you the code to implement it. If you open the CustomControls.xaml file in xaml view, you’ll see the Visual States that are built into the Transitioning Content Control – DefaultTransition, Normal, UpTransition and DownTransition. Find the closing tag of the DownTransition visual state (</VisualState>). Position your cursor at the end of this tag and press enter on the keyboard. Copy and paste in the following code:
<VisualState x:Name="Flipper">
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="CurrentContentPresentationSite" Storyboard.TargetProperty="(UIElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.9000000" Value="0"/>
<EasingDoubleKeyFrame KeyTime="00:00:01" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="PreviousContentPresentationSite" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<EasingDoubleKeyFrame KeyTime="00:00:01" Value="90"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="CurrentContentPresentationSite" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)">
<EasingDoubleKeyFrame KeyTime="00:00:01" Value="-90"/>
<EasingDoubleKeyFrame KeyTime="00:00:02" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
Now, find the Control Template tag that defines the navigation frame. Within this tag, you should see the TransitioningContentControl tag defining the control. Add an attribute to the tag after the Style attribute for the Transition type and give it a value of “Flipper”. It should look like this:
<!-- Resource dictionary entries should be defined here. -->
<ControlTemplate x:Key="NavFrame" TargetType="navigation:Frame">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" d:DesignWidth="639" d:DesignHeight="432">
<layoutToolkit:TransitioningContentControl
Content="{TemplateBinding Content}"
Style="{StaticResource TCCCustom}"
Transition="Flipper"/>
</Border>
</ControlTemplate>
Save and close the file. Switch back to Visual Studio and accept the changes if it asks. Go ahead and press F5 to run the application. You should see the content of the pages flip one way then flip back with the content of the new page.
This is the technique I used to create a customized page transition for use within the Navigation Project template for Silverlight 3. There are many other types of transitions you can implement and play around with, so I hope this has given you a look into what’s possible for this type of animation. In my next post, I’ll go over how I created an animation for displaying a life cycle type graphic using Expression Design and Expression Blend. Hope you found this useful! Thanks for reading!
