I have a control that displays a curve with control points that the user can control. If the user drags a control point outside of the bounds of the control, it is no longer reachable, and so I create a little animation that scales the curve down until all of the control points are visible again. I am using a RectAnimation
on a DependencyProperty
in a surrogate object type to capture the values produced by the animation. This is mostly working, except that randomly, perhaps one time out of ten, the animation suddenly stops partway, no exception, no Completed
event, and the curve hasn’t been fully translated to the target bounds.
Slightly-simplified code:
Rect elementBounds = GetBoundsForControlPoints();
if ((elementBounds.Left < 0) || (elementBounds.Right > ActualWidth)
|| (elementBounds.Top < 0) || (elementBounds.Bottom > ActualHeight))
{
var fitBounds = FitRectangleToVisibleArea(elementBounds); // same aspect but entirely visible
var anim = new RectAnimation();
anim.From = elementBounds;
anim.To = fitBounds;
anim.Duration = TimeSpan.FromSeconds(0.4);
var animTarget = new AnimationTarget();
animTarget.StartRect = elementBounds;
animTarget.EndRect = fitBounds;
animTarget.RectChanged +=
(_, _) =>
{
TranslateControlPoints(animTarget.StartRect, animTarget.Rect);
};
animTarget.BeginAnimation(AnimationTarget.RectProperty, anim);
}
This is the proxy class:
class AnimationTarget : UIElement
{
public static DependencyProperty RectProperty = DependencyProperty.Register(nameof(Rect), typeof(Rect), typeof(AnimationTarget), new UIPropertyMetadata(RectChangedCallback));
public Rect StartRect;
public Rect EndRect;
public Rect Rect
{
get => (Rect)GetValue(RectProperty);
set => SetValue(RectProperty, value);
}
public event EventHandler? RectChanged;
static void RectChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((AnimationTarget)d).RectChanged?.Invoke(d, EventArgs.Empty);
}
}
Most of the time, the animation runs to completion perfectly, but every now and then, it just … stops. The curve is partway along its translation and simply stays there. I can trigger a new animation and it picks up from where the previous one left off.
What might be causing the animations to sometimes just stop partway through?