In Silverlight applications practically everything can be animated to provide visually pleasing transitions between changes in your application or web page. When you hide something that is currently visible, why have it just disappear when you can make it fade away or slide off to the edge of the page? Or both? Silverlight makes these kinds of effects so much easier than ever before… so take advantage of it!
Unfortunately, there’s one control that is surprisingly a pain to support this on… the grid control. Try to animate collapsing its rows or columns by animating ColumnDefinition.Width or RowDefinition.Height via:
<DoubleAnimation Storyboard.TargetName=”Column1″ Storyboard.TargetProperty=”Width” To=”0″ Duration=”00:00:00.5″/>
and you’ll quickly discover the following runtime error:
InvalidOperationException: DoubleAnimation cannot be used to animate property Width due to incompatible type.
It turns out, Width is not of type Double but instead is of type GridLength. And GridLength has a property called Value of type Double, but Value is ReadOnly so to change the width or height you have to create a new instance of the GridLength object and set it it to the Width Property. Unfortunately, this is not something that can be done in a DoubleAnimation (that I’m aware of).
The solution: Do it yourself! Add a Name to the root element of your page, animate your own property and have your your property wrap setting the Width property on the ColumnDefinition or RowDefinition.
<DoubleAnimation Storyboard.TargetName=”Myself” Storyboard.TargetProperty=”ColumnWidth” To=”0″ Duration=”00:00:00.5″/>
' Warning: This does not work from an animation
Public Property ColumnWidth() As Double
Get
Return Column1.Width.Value
End Get
Set(ByVal value As Double)
Column1.Width = New GridLength(value)
End Set
End Property
Private Shared ReadOnly ColumnWidthProperty As DependencyProperty = DependencyProperty.Register("ColumnWidth", GetType(Double), GetType(Page), New Windows.PropertyMetadata(AddressOf ColumnWidthChanged))
Private Property ColumnWidth() As Double
Get
Return DirectCast(GetValue(ColumnWidthProperty), Double)
End Get
Set(ByVal value As Double)
SetValue(ColumnWidthProperty, value)
End Set
End Property
Private Shared Sub ColumnWidthChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
DirectCast(d, Page).Column1.Width = New GridLength(DirectCast(e.NewValue, Double))
End Sub

Hi Tim -
An alternative method would be to set the grid column widths to “Auto”, and then place a “resize” rectangle in the column and animate the rectangle width. As the rectangle expands/contracts, so will the column…
Jeff
You can also animate MinHeight and MaxHeight on the columns/rows as they are dep properties. It is a bit tricky though and I do like your solution.
One other possible enhancement would be to move the Dep property into a separate “helper” class and instead create it as an attached property that way you could easily reuse the code without copy/paste. e.g. name the helper class GridAnimationHelper and the attached property GridLength (to accomodate both rows and columns). Then you could just animate (GridAnimationHelper.GridLength) with a DoubleAnimation just like you would (Canas.Left) and the attached Dep property would handle the rest just as you have above.
Thanks though. I was struggling with this….
[...] I have found this post about animating Grid columns & rows and implemented it in my sample [...]
hi,
i have extended the GridspSplitter and implemented your solution in mine.
please look here:
http://shemesh.wordpress.com/2008/12/03/silverlight-gridsplitter-with-a-collapse-button-v2/
Very useful.. all of you.
Hi,
I have gone through above sample. It’s working fine but it’s in VB. Can you please give me in C#. I have tried to convert that to c# but I am unable to do the below two function -
1. private DoubleAnimation ExpandColumnWidthAnimation
2. private DoubleAnimation CollapseColumnWidthAnimation
atleast please give me above two functions code in c#.
My personal mail ID: ashok.just4u@gmail.com
Hi
I have created the same animation without using a single line of code, by the help of fluid move behaviour.
Hey, i ran into your blog while searching for this solution. I implemented my own later on which is less powerful (no gridsplitter) but it’s xaml only so i thought i’d share it.
http://www.run80.net/?p=84
Nice post. The info presented here was the best I could find all day long, and I have been searching tough on the Web. I believe you ought to put this up on a large social bookmarking site, you will find that it spreads like wildfire – Cheers – dave
Hi All,
Thanks for the solution
And i completely agree with Jo’s suggestion. This solution is simply the best I could find.
Hello,
i have copied the Source Code, but it does not works.
The Error Message when I start the storybord is: “Animation target not set.”
Please can everyone you help me.
Thanks,
Martin
Easier solution using ObjectAnimationUsingKeyFrames :
No real smoothing, but 2-3 intermediate key frames will help.
Kostya
Oops, here code: http://pastebin.com/d5anBhC7
Great website. Plenty of helpful info here. I am sending it to several friends ans also sharing in delicious. And certainly, thank you for your sweat!
Great post. Quick solution. I code in c# and went through the process of converting it. In case anyone else out there needs this bit of code…here it is.
private static readonly DependencyProperty ColumnWidthProperty = DependencyProperty.Register(“ColumnWidth”, typeof(double), typeof(MainPage),
new PropertyMetadata(ColumnWidthChanged));
private double ColumnWidth {
get { return (double)GetValue(ColumnWidthProperty); }
set { SetValue(ColumnWidthProperty, value); }
}
private static void ColumnWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
((MainPage)d).sideBarWidth.Width = new GridLength((double)e.NewValue);
}
Using Lucas’ code, i get an error saying: “Unhandled Error in Silverlight Application Cannot resolve TargetProperty RowHeight on specified object. at MS.Internal.XcpImports.MethodEx(IntPtr ptr, String name, CValue[] cvData)\n at MS.Internal.XcpImports.MethodEx(DependencyObject obj, String name)\n at System.Windows.Media.Animation.Storyboard.Begin()\n at VideoWebsitePractice.MainPage.HideToolbar_Click(Object sender, RoutedEventArgs e)\n at System.Windows.Controls.Primitives.ButtonBase.OnClick()\n at System.Windows.Controls.Button.OnClick()\n at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)\n at System.Windows.Controls.Control.OnMouseLeftButtonUp(Control ctrl, EventArgs e)\n at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)”);
Instead of using Column Width, i am using row height because i want an animated row. Anyone know what the issue could possibly be?
Travis, you’ll need to change ColumnWidth to RowHeight in the .xaml file too.