Reputation: 2245
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
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
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