Drarig29
Drarig29

Reputation: 2245

How to remove animation after it's completed

I'd like to remove the animation from my target property because i'm Unable to set the property after its animation.

So, according to the answer of the question above, I've to remove the animation after it's completed. But how to do it ?

Here's my code:

public class GridLengthAnimation : AnimationTimeline {

    static GridLengthAnimation() {
        FromProperty = DependencyProperty.Register("From", typeof(GridLength), typeof(GridLengthAnimation));
        ToProperty = DependencyProperty.Register("To", typeof(GridLength), typeof(GridLengthAnimation));
    }

    public override Type TargetPropertyType {
        get { return typeof(GridLength); }
    }

    protected override Freezable CreateInstanceCore() {
        return new GridLengthAnimation();
    }

    public ContentElement Target { get; set; }

    public static readonly DependencyProperty FromProperty;
    public GridLength From {
        get { return (GridLength) GetValue(FromProperty); }
        set { SetValue(FromProperty, value); }
    }

    public static readonly DependencyProperty ToProperty;
    public GridLength To {
        get { return (GridLength) GetValue(ToProperty); }
        set { SetValue(ToProperty, value); }
    }

    public void BeginAnimation() {
        Target.BeginAnimation(ColumnDefinition.WidthProperty, null);
        Target.BeginAnimation(ColumnDefinition.WidthProperty, this);
    }

    public IEasingFunction EasingFunction { get; set; } = new CubicEase() { EasingMode = EasingMode.EaseInOut };

    public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock) {
        double fromValue = ((GridLength) GetValue(FromProperty)).Value;
        double toValue = ((GridLength) GetValue(ToProperty)).Value;
        double newValue = 0;

        if ((fromValue > toValue)) {
            newValue = (1 - EasingFunction.Ease(animationClock.CurrentProgress.Value)) * (fromValue - toValue) + toValue;
            return new GridLength(newValue, GridUnitType.Star);
        } else {
            newValue = EasingFunction.Ease(animationClock.CurrentProgress.Value) * (toValue - fromValue) + fromValue;
            return new GridLength(newValue, GridUnitType.Star);
        }
    }
}

To begin the animation, I do it this way in my MainWindows.xaml.cs file:

GridLengthAnimation gridAnim = new GridLengthAnimation() {
    Name = "gridAnim",
    Target = mainGrid.ColumnDefinitions[1],
    Duration = new Duration(TimeSpan.FromMilliseconds(1000))
};

gridAnim.From = new GridLength(1, GridUnitType.Star);
gridAnim.To = new GridLength(0, GridUnitType.Star);

gridAnim.BeginAnimation();

Where could I remove the animation after it's completed?

Upvotes: 1

Views: 886

Answers (2)

Drarig29
Drarig29

Reputation: 2245

I found my solution here, in the "Remove an animation from an individual property" part.

I added this in my GridLengthAnimation:

public void BeginAnimation() {
    Completed += GridLengthAnimation_Completed;
    Target.BeginAnimation(ColumnDefinition.WidthProperty, null);
    Target.BeginAnimation(ColumnDefinition.WidthProperty, this);
}

private void GridLengthAnimation_Completed(object sender, EventArgs e) {
    //unlocks the property
    Target.BeginAnimation(ColumnDefinition.WidthProperty, null);

    //holds the value at the end
    ((ColumnDefinition) Target).Width = new GridLength(((GridLength) GetValue(ToProperty)).Value, GridUnitType.Star);
}

Upvotes: 0

lokusking
lokusking

Reputation: 7456

Just change your usage to:

    GridLengthAnimation gridAnim = new GridLengthAnimation() {
            Name = "gridAnim",
            Target = this.MainGrid.ColumnDefinitions[1],
            Duration = new Duration(TimeSpan.FromMilliseconds(1000))
          };

          gridAnim.From = new GridLength(1, GridUnitType.Star);
          gridAnim.To = new GridLength(0, GridUnitType.Star);
//Cleanup on Complete
          gridAnim.Completed += (sender, args) => {
                                                    var xx = sender as AnimationClock;
                                                    (xx.Timeline as GridLengthAnimation).Target = null;
          };
          gridAnim.BeginAnimation();

Upvotes: 1

Related Questions