Introduction
I have seen this question come up a lot and did not come across a simple answer. Perhaps, I just wasn't looking hard enough! But any how, I thought I would share my experience. This was the very first thing I tried to do in Silverlight and although I knew what I needed to do conceptually, I struggled finding my way around a little. However, I got there after a couple of hours. Hopefully, this will get people going a lot quicker than I did!
If you want to see the code and run the sample, you can download the solution from above!
I started by creating a user control in Blend which I encapsulated all my behavior into. I then created my mouse enter Storyboard
which I will not go into in too much detail. The XAML is given below:
<Storyboard x:Name="flipforward" Duration="00:00:03">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="userControl"
Storyboard.TargetProperty="(UIElement.Projection)
.(PlaneProjection.RotationY)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="45"/>
<SplineDoubleKeyFrame KeyTime="00:00:01" Value="25"/>
<SplineDoubleKeyFrame KeyTime="00:00:03" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
I then used Blend to create a copy of this and used the reverse command in Blend to, you guessed it, reverse the Storyboard
! Which looks like this:
<Storyboard x:Name="flipback" Duration="00:00:03">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="userControl"
Storyboard.TargetProperty="(UIElement.Projection)
.(PlaneProjection.RotationY)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<SplineDoubleKeyFrame KeyTime="00:00:02" Value="25"/>
<SplineDoubleKeyFrame KeyTime="00:00:03" Value="45"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
In the code-behind of my user control (of course, you should try to avoid using code-behind in production code!), I override the mouse enter and leave events with the following code:
protected override void OnMouseEnter(MouseEventArgs e)
{
var flipstoryboard = Resources["flipforward"]
as Storyboard;
if (flipstoryboard != null) flipstoryboard.Begin();
}
protected override void OnMouseLeave(MouseEventArgs e)
{
var forwardstoryboard = Resources["flipforward"]
as Storyboard;
var flipstoryboard = Resources["flipback"] as Storyboard;
if (flipstoryboard != null &&
forwardstoryboard != null)
{
var duration = flipstoryboard.Duration;
flipstoryboard.Begin();
flipstoryboard.Seek(
duration.TimeSpan -
forwardstoryboard.GetCurrentTime());
}
}
The mouse enter event simply gets a reference to my enter Storyboard and begins it. The mouse leave event needs to do a bit more efficient since we want the reverse animation to be smooth. If we just called the Begin
method, the reverse animation would play from the start which would make it look jumpy if you moved the mouse away before the first Storyboard
completed. What we need to do is find out where the first Storyboard
currently is and fast forward the reverse animation to the same point.
I hope this was helpful.
We cannot achieve perfection but we can strive for excellence. Excellence through creativity that pushes innovation, collaboration that facilitates productivity, knowledge that empowers people and persistence that eventually pays off !
Enjoy what you do and do what you enjoy !