If you had problems with animating gridcolumn widths or gridrow heights i have a solution for your problems. put the following class somewhere in your project:
using System.Windows; using System.Windows.Controls; using System.Windows.Media.Animation; namespace AltinetSilver.Animations { public static class GridLengthAnimation { //you only have to set the rowdefinition or columnDefinition! #region Element (Attached DependencyProperty) public static readonly DependencyProperty ElementProperty = DependencyProperty.RegisterAttached("Element", typeof(DependencyObject), typeof(DoubleAnimation), new PropertyMetadata(new PropertyChangedCallback(OnElementPropertyChanged))); public static void SetElement(DependencyObject o, DependencyObject value) { o.SetValue(ElementProperty, value); } public static DependencyObject GetElement(DependencyObject o) { return (DependencyObject)o.GetValue(ElementProperty); } private static void OnElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (e.NewValue != null) { DoubleAnimation timeAnimation = (DoubleAnimation)d; var target = e.NewValue; timeAnimation.SetValue(TargetProperty, target); DependencyProperty targetProperty; GridUnitType gType; if (target is ColumnDefinition) { targetProperty = ColumnDefinition.WidthProperty; gType = ((ColumnDefinition)target).Width.GridUnitType; } else { targetProperty = RowDefinition.HeightProperty; gType = ((RowDefinition)target).Height.GridUnitType; } timeAnimation.SetValue(TargetPropertyProperty, targetProperty); timeAnimation.SetValue(TargetUnitTypeProperty, gType); Storyboard.SetTargetProperty(timeAnimation, new PropertyPath("(GridLengthAnimation.Time)")); Storyboard.SetTarget(timeAnimation, timeAnimation); } } #endregion // The time along the animation from 0-1 public static DependencyProperty TimeProperty = DependencyProperty.RegisterAttached("Time", typeof(double), typeof(DoubleAnimation), new PropertyMetadata(OnTimeChanged)); // The object being animated public static DependencyProperty TargetProperty = DependencyProperty.RegisterAttached("Target", typeof(DependencyObject), typeof(GridLengthAnimation), null); public static DependencyProperty TargetPropertyProperty = DependencyProperty.RegisterAttached("TargetProperty", typeof(DependencyProperty), typeof(DependencyObject), null); public static DependencyProperty TargetUnitTypeProperty = DependencyProperty.RegisterAttached("TargetUnitType", typeof( GridUnitType), typeof( DependencyObject ), null); /// <summary> /// Silverlight's animation system is animating time from 0 to 1. When time changes we update the grid length to be time /// percent between from and to /// </summary> private static void OnTimeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { DoubleAnimation animation = (DoubleAnimation)sender; double time = GetTime(animation); DependencyProperty targetProperty = (DependencyProperty)sender.GetValue(TargetPropertyProperty); DependencyObject target = (DependencyObject)sender.GetValue(TargetProperty); GridUnitType gType = (GridUnitType) sender.GetValue(TargetUnitTypeProperty); target.SetValue(targetProperty, new GridLength(time, gType)); } public static double GetTime(DoubleAnimation animation) { return (double)animation.GetValue(TimeProperty); } public static void SetTime(DoubleAnimation animation, double value) { animation.SetValue(TimeProperty, value); } } }
And the usage model would look something like this
<VisualStateGroup x:Name="NotesStateGroup"> <VisualState x:Name="NotesVisible"> <Storyboard> <DoubleAnimation From="0" To="4" Duration="0:0:0.15" Animations:GridLengthAnimation.Element="{Binding ElementName=Column2}"/> </Storyboard> </VisualState> <VisualState x:Name="NotesCollapsed"> <Storyboard> <DoubleAnimation From="4" To="0" Duration="0:0:0.15" Animations:GridLengthAnimation.Element="{Binding ElementName=Column2}"/> </Storyboard> </VisualState> </VisualStateGroup>
The important part is in DoubleAnimation tag where you set the extended property GridLengthAnimation.Element where column2 is a name of a column. 3 and 0 are starred values. but with some tweaking of this simple model, you can basically do whatever you want.
UPDATE: I have updated the code, now it supports both starred and fixed column/row widths/heights.
Enjoy!
UPDATE 2 I’ve put a more complete code for one of the controls here as per request in the comment.
<UserControl x:Class="AltiAgent.PartnerPage.PartnersView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="700" d:DesignWidth="1300" xmlns:Animations="clr-namespace:AltiSilverlight.Animations;assembly=AltiSilverlight" x:Name="PartnersUserControl" Animations:StateManager.CurrentState="{Binding CurrentVisualState}" > <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="NotesStateGroup"> <VisualState x:Name="NotesVisible"> <Storyboard> <DoubleAnimation From="0" To="400" Duration="0:0:0.15" Animations:GridLengthAnimation.Element="{Binding ElementName=Column2}"/> </Storyboard> </VisualState> <VisualState x:Name="NotesCollapsed"> <Storyboard> <DoubleAnimation From="400" To="0" Duration="0:0:0.15" Animations:GridLengthAnimation.Element="{Binding ElementName=Column2}"/> </Storyboard> </VisualState> </VisualStateGroup> <VisualStateGroup x:Name="DetailsStateGroup"> <VisualState x:Name="DetailsVisible"> <Storyboard> <DoubleAnimation From="0" To="300" Duration="0:0:0.15" Animations:GridLengthAnimation.Element="{Binding ElementName=Column1}"/> </Storyboard> </VisualState> <VisualState x:Name="DetailsCollapsed"> <Storyboard> <DoubleAnimation From="300" To="0" Duration="0:0:0.15" Animations:GridLengthAnimation.Element="{Binding ElementName=Column1}"/> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Grid.ColumnDefinitions> <ColumnDefinition x:Name="Column0" Width="*" /> <ColumnDefinition x:Name="Column1" Width="300" /> <ColumnDefinition x:Name="Column2" Width="400" /> </Grid.ColumnDefinitions> <ContentControl x:Name="PartnerGridPart"/> <ContentControl Grid.Column="1" x:Name="PartnerForm"/> <ContentControl Grid.Column="2" x:Name="TaskNoteListPart"/> </Grid> </UserControl>
Martin Hülsewis Mar 29 , 2011 at 9:51 am /
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 you help me.
Thanks,
Martin
This XAML-Code i have used
——————————————————–
Bruno Mar 29 , 2011 at 10:10 am /
Hmm, i don’t see your xaml code, it probably gets cut out or something by comments system. Try emailing me to the email in contacts. Btw i updated the code, so be sure to try it with the new code
Mike Jan 17 , 2013 at 2:54 pm /
How would I do an animation using star values in xaml? I tried this, but start is not allowed for “From” or “To” in DoubleAnimation:
kagjes Feb 12 , 2013 at 1:05 am /
Hi Mike, you don’t use stars in from and to, if the column is already defined as a star width, it will be modified to another star value. So no need for star there. On the other hand, if you want to switch from fixed to star column, you will have to update the code. Hope this helps!
Yossu Mar 03 , 2013 at 5:51 pm /
Hello,
Please can you provide a more complete XAML sample? I’m new at animations, and need to do something like you describe, but am not sure how to use the XAML you show. I tried searching on VisualStateGroup, but it’s very confusing for a beginner.
My requirement is to make a pop-out panel, like Microsoft Word has for its help. You click a little button at the top right, and a panel smoothly opens up on the right side of the window. If you could show how to do something like that, it would be great.
Thanks
kagjes Mar 03 , 2013 at 9:41 pm /
Ok, i pasted a more complete XAML there. As for VisualStateGroup, you should catch up on a few tutorials about animation to understand the states and transitions. I am using MVVM in my solution so that might confuse you even more if you are a beginner (you can see an attached StateManager in the usercontrol tag, but what that basically does is changes states by setting a property in the viewmodel, you can do it directly by setting it directly to VisualStateManager. I hope this is more helpful, i don’t have a small enough project to upload with transitions set up. There are some nice resources on internet, like the following:
http://www.silverlightshow.net/items/Custom-ContentControl-using-VisualStateManager.aspx
Hope that helps!
Yossu Mar 04 , 2013 at 1:46 pm /
Thanks for that, both the example and link were excellent!
Angshuman May 19 , 2021 at 9:30 pm /
Hi, Can you please share a sample code that works with a column with ‘auto’ width?