Mark Gilbert's Blog

Science and technology, served light and fluffy.

WPF Animations (3 of 3)

In my previous two posts in this series, I’ve gone through defining and triggering animations in markup, and defining animations in markup but triggering them in code.  Now, we’ll look at animations that are both defined and triggered in code.  All of this code comes from the WPF Media Player sample application.

My example here is the ShowAlbumFlyout method of the Main window.  The first couple of lines of this method trigger the control to be made visible (as we discussed in my previous post), but the rest of the method controls the animation involved in showing the JewelCaseExpand user control sliding down, as if it is being taken down off the shelf.

Before we can talk about the animation code, however, I need to point out a trick that I’m employing.  The JewelCase is placed on the form and hidden using the Main.CurrentJewelCaseExpand property.  This property looks at the _CurrentJewelCaseExpand variable on the form, and if it isn’t instantiated already, instantiates it.  When I do this, by default, the control gets dropped onto the very center of the form.

I tried several different ways to make the control move around using (X,Y) coordinates, but the control just doesn’t have support for .Location, .Left, .Top, etc..  I ended up getting it to move via some sleight of hand.  I found that I could adjust the alignment using the control’s HorizontalAlignment and VerticalAlignment properties.  I also found that I could fake moving it by adjusting the control’s Margin thickness.  With these two facts, I can effectively move the JewelCaseExpand control to wherever I need it:

Me.CurrentJewelCaseExpand.HorizontalAlignment = Windows.HorizontalAlignment.Left

Me.CurrentJewelCaseExpand.VerticalAlignment = Windows.VerticalAlignment.Top

Me.CurrentJewelCaseExpand.Margin = New Thickness(e.JewelCaseBottomLeftCorner.X, e.JewelCaseBottomLeftCorner.Y – 20, 0, 0)

This shoves the control into the upper left corner, and then adjusts the Margin’s left thickness to align with the JewelCases’s lower left corner (flush left, and higher by 20 pixels).

Manipulating the Margin like this also sets up how the animation works.  If I want it to appear as though it was sliding down, I just create an animation that adjusts the Margin of the control.  I begin by defining the “SlideUpAnimation”:

SlideUpAnimation = New Animation.ThicknessAnimation(New Thickness(e.JewelCaseBottomLeftCorner.X, e.JewelCaseBottomLeftCorner.Y – 20, 0, 0), _

     New Thickness(e.JewelCaseBottomLeftCorner.X, e.JewelCaseBottomLeftCorner.Y + 5, 0, 0), _

     New Duration(New TimeSpan(0, 0, 0, 0, 200)))

The ThicknessAnimation constructor that I’m using here takes three parameters – the beginning Thickness, the ending Thickness, and the Duration in which to adjust the Margin from the former to the latter.

Next, just like in the markup examples, an Animation is a child element of a Storyboard, so we need to define that here and add the SlideUpAnimation to it:

MyStoryBoard = New Storyboard


Next, I need to configure the Storyboard to affect the correct property of the correct object (again, just like in markup):

Storyboard.SetTargetName(SlideUpAnimation, Me.CurrentJewelCaseExpand.Name)

Storyboard.SetTargetProperty(SlideUpAnimation, New PropertyPath(JewelCaseExpand.MarginProperty))

Finally, I start the animation:



Why did I need to define this and trigger this animation in code?  The JewelCaseExpand control needs to appear relative to the JewelCase that the user mouses over, and that information is not known at design time.

We’ve now looked at what I think are three major buckets for defining and triggering animations in WPF.  The WPF Media Player has several other notable aspects (especially surrounding the use of LINQ to XML), and we’ll look at those in later posts.


(On an amusing note, while writing this post I discovered that the name of the Animation object, SlideUpAnimation, is misleading.  Originally I had planned on the animation coming up from the bottom, but I’ve since changed it to drop down, but neglected to update the variable name to match.  I’ll correct that in the next release.)




March 7, 2008 - Posted by | WPF/Silverlight

Sorry, the comment form is closed at this time.

%d bloggers like this: