(This post extends my example for using cross project merged dictionaries in Silverlight)
I’m a developer, not a designer and as such using Expression Blend doesn’t feel natural and makes me feel dirty… However I had to bite the bullet to ease the restyling of the transition animation in the Toolkit TransitioningContentControl.
NOTE: At time of writing this control is in the Experimental Quality Band – the way I have built this might not work in the future!!
To edit the transition in blend I added a TCC to my page, right clicked and chose “Edit Template Edit a Copy… Define in Application”
You can then start editing the VisualStates. There is tons of information on how to do this, so I won’t repeat that here, but here are the basics:
Select States tab, Choose a transition to edit (or add a new one) expand the objects and make changes to the states along the time line.
After making changes to your template open it and examine the changes. Most stuff is pretty self explanatory. Once this is done I can close blend and copy the XAML in to Visual Studio – now I feel safe and clean!!
So, I wanted to add a flip transition, that makes the page look like it is doing a 360 flip around a vertical axis. First thing to do is edit the content template to include project planes, as these are hooked from my new animation (lines 17-19 and 37-39 below). You won’t need to do this is you are changing basic animation properties (offset, opacity, scale etc):
<ContentPresenter x:Name="PreviousContentPresentationSite"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{x:Null}"
ContentTemplate="{TemplateBinding ContentTemplate}">
<ContentPresenter x:Name="CurrentContentPresentationSite"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{x:Null}"
ContentTemplate="{TemplateBinding ContentTemplate}">
Then add my flip animation (lines 53-74 below):
<Style x:Key="TransitioningContentControlStyle1"
TargetType="layoutToolkit:TransitioningContentControl">
<Setter Property="IsTabStop"
Value="True" />
<Setter Property="HorizontalContentAlignment"
Value="Left" />
<Setter Property="VerticalContentAlignment"
Value="Top" />
<Setter Property="Transition"
Value="DefaultTransition" />
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="CurrentContentPresentationSite"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00"
Value="0" />
<SplineDoubleKeyFrame KeyTime="00:00:00.300"
Value="1" />
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="PreviousContentPresentationSite"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00"
Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.300"
Value="0" />
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="PreviousContentPresentationSite"
Storyboard.TargetProperty="(UIElement.Visibility)">
Collapsed
<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:00.3000000"
Value="90" />
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="CurrentContentPresentationSite"
Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)">
<EasingDoubleKeyFrame KeyTime="00:00:00"
Value="-90" />
<EasingDoubleKeyFrame KeyTime="00:00:00.3000000"
Value="-90" />
<EasingDoubleKeyFrame KeyTime="00:00:00.6000000"
Value="0" />
<ContentPresenter x:Name="PreviousContentPresentationSite"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{x:Null}"
ContentTemplate="{TemplateBinding ContentTemplate}">
<ContentPresenter x:Name="CurrentContentPresentationSite"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{x:Null}"
ContentTemplate="{TemplateBinding ContentTemplate}">
NOTE: I have removed the DefaultTransition, UpTransition and DownTransition VisualStates from this code as I am not using them. Normal MUST remain. If you want these transition states back they are copied below for your convenience.
Finally I copied this style to a separate file so it can be referenced as a MergedDictionary across a multi project solution (as described here).
When doing this, remember to Add a reference to System.Windows.Controls.Toolkit and System.Windows.Controls.Layout.Toolkit from the resources project, and in the resource xaml file:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:layoutToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Layout.Toolkit">
DefaultTransition, UpTransition and DownTransition Visual States
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="CurrentContentPresentationSite"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00"
Value="0" />
<SplineDoubleKeyFrame KeyTime="00:00:00.300"
Value="1" />
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="PreviousContentPresentationSite"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00"
Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.300"
Value="0" />
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="CurrentContentPresentationSite"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00"
Value="0" />
<EasingDoubleKeyFrame KeyTime="00:00:00.7330000"
Value="0" />
<EasingDoubleKeyFrame KeyTime="00:00:01.1000000"
Value="1" />
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="PreviousContentPresentationSite"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00"
Value="1" />
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000"
Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000"
Value="0" />
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="PreviousContentPresentationSite"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
<EasingDoubleKeyFrame KeyTime="00:00:00"
Value="0">
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000"
Value="0">
<EasingDoubleKeyFrame KeyTime="00:00:00.9000000"
Value="0">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="CurrentContentPresentationSite"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="00:00:00.7330000"
Value="0" />
<EasingDoubleKeyFrame KeyTime="00:00:01.1000000"
Value="1" />
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="CurrentContentPresentationSite"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="00:00:00.7330000"
Value="0" />
<EasingDoubleKeyFrame KeyTime="00:00:01.1000000"
Value="1" />
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="PreviousContentPresentationSite"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="00:00:00"
Value="1">
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000"
Value="0.75">
<EasingDoubleKeyFrame KeyTime="00:00:00.9000000"
Value="1">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="PreviousContentPresentationSite"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="00:00:00"
Value="1">
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000"
Value="0.75">
<EasingDoubleKeyFrame KeyTime="00:00:00.9000000"
Value="1">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="PreviousContentPresentationSite"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000"
Value="0">
<EasingDoubleKeyFrame KeyTime="00:00:00.9000000"
Value="-500">
<PointAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="PreviousContentPresentationSite"
Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)">
<EasingPointKeyFrame KeyTime="00:00:00"
Value="0.5,0.5" />
<EasingPointKeyFrame KeyTime="00:00:00.5000000"
Value="0.5,0.5" />
<PointAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="CurrentContentPresentationSite"
Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)">
<EasingPointKeyFrame KeyTime="00:00:00"
Value="0.5,0.5" />
<EasingPointKeyFrame KeyTime="00:00:00.7330000"
Value="0.5,0.5" />
<EasingPointKeyFrame KeyTime="00:00:01.1000000"
Value="0.5,0.5" />
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="CurrentContentPresentationSite"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00"
Value="0" />
<SplineDoubleKeyFrame KeyTime="00:00:00.300"
Value="1" />
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="CurrentContentPresentationSite"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
<SplineDoubleKeyFrame KeyTime="00:00:00"
Value="-40" />
<SplineDoubleKeyFrame KeyTime="00:00:00.300"
Value="0" />
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="PreviousContentPresentationSite"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00"
Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.300"
Value="0" />
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="PreviousContentPresentationSite"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
<SplineDoubleKeyFrame KeyTime="00:00:00"
Value="0" />
<SplineDoubleKeyFrame KeyTime="00:00:00.300"
Value="40" />
Note: UpTransition has been altered to do a funky “drop-back-swing-left-and-fade-in” animation
Great post! I shudder when I have to use Blend (I too am a developer, not a designer), so I used your XAML for a great Flip effect.
Thanks Cuperman.