Animating height and width
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
'System.Windows.Media.Animation.DoubleAnimation'.
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.