Wer die Spalten eines Grid-Elementes animieren möchte, findet keine entsprechende Animationsklasse im .NET Framework. Eine eigene Ableitung muss her. Hier in aller Kürze die Implementierung:

public class GridLengthAnimation : AnimationTimeline

{

    public override Type TargetPropertyType

    {

        get { return typeof(GridLength); }

    }

 

    protected override System.Windows.Freezable CreateInstanceCore()

    {

        return new GridLengthAnimation();

    }

 

    public static readonly DependencyProperty FromProperty = 

        DependencyProperty.Register("From", typeof(GridLength), typeof(GridLengthAnimation));

 

    public GridLength From

    {

        get

        {

            return (GridLength)GetValue(GridLengthAnimation.FromProperty);

        }

        set

        {

            SetValue(GridLengthAnimation.FromProperty, value);

        }

    }

 

    private double FromAsDouble

    {

        get

        {

            return ((GridLength)From).Value;

        }

    }

 

    public static readonly DependencyProperty ToProperty = 

        DependencyProperty.Register("To", typeof(GridLength), typeof(GridLengthAnimation));

        

    public GridLength To

    {

        get

        {

            return (GridLength)GetValue(GridLengthAnimation.ToProperty);

        }

        set

        {

            SetValue(GridLengthAnimation.ToProperty, value);

        }

    }

 

    private double ToAsDouble

    {

        get

        {

            return ((GridLength)To).Value;

        }

    }

 

    public GridUnitType GridUnitType

    {

        get { return (GridUnitType)GetValue(GridUnitTypeProperty); }

        set { SetValue(GridUnitTypeProperty, value); }

    }

 

    public static readonly DependencyProperty GridUnitTypeProperty =

        DependencyProperty.Register("GridUnitType", typeof(GridUnitType), typeof(GridLengthAnimation), new UIPropertyMetadata(GridUnitType.Pixel));

 

    public override object GetCurrentValue(object defaultOriginValue, 

                                            object defaultDestinationValue, 

                                            AnimationClock animationClock)

    {

        if (FromAsDouble > ToAsDouble)

            return new GridLength((1 - animationClock.CurrentProgress.Value) *

                (FromAsDouble - ToAsDouble) + ToAsDouble, this.GridUnitType);

            

        return new GridLength(animationClock.CurrentProgress.Value *

            (ToAsDouble - FromAsDouble) + FromAsDouble, this.GridUnitType);

    }

}

Angeboten werden drei Eigenschaften:

  • From: double-Wert für den ausgehenden Wert
  • To: double-Wert für den Wert bis zu dem animiert werden soll
  • GridUnitType: Der anzuwendende GridUnitType (Auto, Stern, Pixel)

Die Verwendung ist äußerst einfach, hier per Code gezeigt:

private void AnimateDetailPane(double from, double to, FrameworkElement element)

{

    GridLengthAnimation gridLengthAnim = new GridLengthAnimation();

    gridLengthAnim.GridUnitType = GridUnitType.Pixel;

    gridLengthAnim.From = new GridLength(from);

    gridLengthAnim.To = new GridLength(to);

    gridLengthAnim.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 300));

 

    Storyboard.SetTargetName(gridLengthAnim, element.Name);

    Storyboard.SetTargetProperty(gridLengthAnim, new PropertyPath("Width"));

 

    Storyboard board = new Storyboard();

    board.Children.Add(gridLengthAnim);

            

    board.Begin(this);

}

Das war es dann auch schon wieder. Weitere notwendige Animationsklassen können nach demselben Schema implementiert werden.

Weitere Informationen zu diesem Thema sind im MSDN unter Animation und zeitliche Steuerung zu finden.

Über den Autor

Norbert Eder

Ich bin ein leidenschaftlicher Softwareentwickler und Fotograf. Mein Wissen und meine Gedanken teile ich nicht nur hier im Blog, sondern auch in Fachartikeln und Büchern.