diff --git a/src/Avalonia.Animation/Animation.cs b/src/Avalonia.Animation/Animation.cs
index c228a49ec7..56bc667f8a 100644
--- a/src/Avalonia.Animation/Animation.cs
+++ b/src/Avalonia.Animation/Animation.cs
@@ -12,13 +12,14 @@ using System.Reflection;
using System.Linq;
using System.Threading.Tasks;
using System.Reactive.Linq;
+using System.Reactive.Disposables;
namespace Avalonia.Animation
{
///
/// Tracks the progress of an animation.
///
- public class Animation : AvaloniaList, IDisposable, IAnimation
+ public class Animation : AvaloniaList, IAnimation
{
private readonly static List<(Func Condition, Type Animator)> Animators = new List<(Func, Type)>
{
@@ -43,7 +44,6 @@ namespace Avalonia.Animation
return null;
}
- private List _subscription = new List();
public AvaloniaList _animators { get; set; } = new AvaloniaList();
///
@@ -76,10 +76,11 @@ namespace Avalonia.Animation
///
public Easing Easing { get; set; } = new LinearEasing();
- private IList InterpretKeyframes(Animatable control)
+ private (IList Animators, IList subscriptions) InterpretKeyframes(Animatable control)
{
var handlerList = new List<(Type type, AvaloniaProperty property)>();
var animatorKeyFrames = new List();
+ var subscriptions = new List();
foreach (var keyframe in this)
{
@@ -104,7 +105,7 @@ namespace Avalonia.Animation
var newKF = new AnimatorKeyFrame(handler, cue);
- _subscription.Add(newKF.BindSetter(setter, control));
+ subscriptions.Add(newKF.BindSetter(setter, control));
animatorKeyFrames.Add(newKF);
}
@@ -126,32 +127,21 @@ namespace Avalonia.Animation
animator.Add(keyframe);
}
- return newAnimatorInstances;
- }
-
- ///
- /// Cancels the animation.
- ///
- public void Dispose()
- {
- foreach (var sub in _subscription)
- {
- sub.Dispose();
- }
+ return (newAnimatorInstances, subscriptions);
}
///
public IDisposable Apply(Animatable control, IObservable match, Action onComplete)
{
- var animators = InterpretKeyframes(control);
+ var (animators, subscriptions) = InterpretKeyframes(control);
if (animators.Count == 1)
{
- _subscription.Add(animators[0].Apply(this, control, match, onComplete));
+ subscriptions.Add(animators[0].Apply(this, control, match, onComplete));
}
else
{
var completionTasks = onComplete != null ? new List() : null;
- foreach (IAnimator animator in InterpretKeyframes(control))
+ foreach (IAnimator animator in animators)
{
Action animatorOnComplete = null;
if (onComplete != null)
@@ -160,7 +150,7 @@ namespace Avalonia.Animation
animatorOnComplete = () => tcs.SetResult(null);
completionTasks.Add(tcs.Task);
}
- _subscription.Add(animator.Apply(this, control, match, animatorOnComplete));
+ subscriptions.Add(animator.Apply(this, control, match, animatorOnComplete));
}
if (onComplete != null)
@@ -168,7 +158,7 @@ namespace Avalonia.Animation
Task.WhenAll(completionTasks).ContinueWith(_ => onComplete());
}
}
- return this;
+ return new CompositeDisposable(subscriptions);
}
///
@@ -179,7 +169,12 @@ namespace Avalonia.Animation
if (this.RepeatCount == RepeatCount.Loop)
run.SetException(new InvalidOperationException("Looping animations must not use the Run method."));
- this.Apply(control, Observable.Return(true), () => run.SetResult(null));
+ IDisposable subscriptions = null;
+ subscriptions = this.Apply(control, Observable.Return(true), () =>
+ {
+ run.SetResult(null);
+ subscriptions.Dispose();
+ });
return run.Task;
}