A developer’s view

Animating height and width

· Read in about 2 min · (423 Words)
WPF Animation

One of the most cool features of WPF is animation. WPF has a great architecture that offers almost unlimited possibilities, but every time I wanted to animate the Height and Width properties I had problems, because the Height and Width properties are often set to the Auto value (which is internally represented as double.NaN). The DoubleAnimation class cannot deal with this value. It uses From and To properties and calculates the values in between.

If the From property isn’t set, then DoubleAnimation starts with the current value and tries to animate to the To property. If the current value is double.NaN, then it cannot interpolate the intermediate values and throws the following exception:

Cannot animate the 'Height' property on a 'xxx' using a

There is not a lot you can do about this one. I tried to bind the From property to the ActualHeight property. Although this might work when collapsing from ActualHeight to 0, there is no way to get expand it again, because you cannot go back to ActualHeight. I also tried to bind to DesiredSize.Height, but I wasn’t successful. There is another disadvatage when using animation with binding, because the entire storyboard needs to be froozen and this isn’t possible when you use binding in the storyboard.

Animating the Height property seems to be impossible, so we should divert to another scenario. A popular approach is to use LayoutTransform and use a ScaleTransform that animates the ScaleY property from 1 to 0 and back again. Although this works, the effect is quite different then animating the Height property (see my attached sample application for the difference). Another disadvantage is that it doesn’t respect the MinHeight and MaxHeight properties.

I decided to use a different approach and to adjust the size of the control by overriding the MeasureOverride method. This method multiplies the requested size with two new dependency properties and returns this new size. This works and because the multiply properties are set to 1.0 by default you don’t notice the control. Animating the multiplier to 0 hides the control completely and animating it back to 1.0 uncovers the entire control.

I called this control the SizerControl and provided source code with it to demonstrate how it works. I tried to convert the control to a Transform class (CropTransform) to be able to use it as a LayoutTransform, but I couldn’t find decent documentation about creating custom transformations. Full source code of the SizerControl can be found in SizerControl.cs. An example can be found in TestWindow.xaml.

Animation test (source)