Altinet
  • Home
  • Blog
  • Contact





Animation for starred grid rows and columns using xaml

On 24 Jan, 2011
Uncategorized
By : Bruno Samardzic
With 8 Comments
Views : 14477

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>


Previous Post Next Post 

About The Author

Bruno Samardzic


Number of Posts : 45
All Posts by : Bruno Samardzic

Comments ( 8 )

  • Martin Hülsewis Mar 29 , 2011 at 9:51 am / Reply

    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 / Reply

    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 / Reply

    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 / Reply

    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 / Reply

    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 / Reply

      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 / Reply

        Thanks for that, both the example and link were excellent!

  • Angshuman May 19 , 2021 at 9:30 pm / Reply

    Hi, Can you please share a sample code that works with a column with ‘auto’ width?


Leave a Comment

Click here to cancel reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>





Recent Posts

  • Angular vs React: round 2
  • Why programming is hard
  • Orchard Workflows, undocumented gem
  • The React Redux
  • React.js invoicing CRUD application, part 2: Description

Recent Comments

  • Angshuman on Animation for starred grid rows and columns using xaml
  • Advanced Excel Training in Lucknow on Angular vs React: round 2
  • Reginald Sophomore on My example of Angularjs directive
  • Slobodan on Angular and Breeze – story so far.
  • Bruno Samardzic on Reaction to Ember-forged Durandal Angularly Knocking out my Backbone, or my JS MVC framework research conclusion.

Contact

Altinet d.o.o.

OIB: 97429091194

Čulinečka cesta 146, Zagreb

Tel: +385 (1) 2946 819

Mob: +385 (98) 210 756

IBAN: HR4323400091110406470

Latest tweets