2

我尝试将 DependencyProperty 从一个值动画到目标值(在代码中),当动画完成(或被取消)时,将最终值设置为属性。最终值将是动画结束时的 To 值或取消动画时的当前计算值(由动画)。

默认情况下,动画没有这种行为,即使动画已经完成,它也不会改变实际值。

一次失败的尝试

前段时间我写了这个辅助方法来实现上述行为:

static void AnimateWithAutoRemoveAnimationAndSetFinalValue(IAnimatable element,
    DependencyProperty property,
    AnimationTimeline animation)
{
    var obj = element as DependencyObject;
    if (obj == null)
        throw new ArgumentException("element must be of type DependencyObject");
    EventHandler handler = null;
    handler = (sender, e) =>
    {
        var finalValue = obj.GetValue(property);
        //remove the animation
        element.BeginAnimation(property, null);
        //reset the final value
        obj.SetValue(property, finalValue);

        animation.Completed -= handler;

    };

    animation.Completed += handler;

    element.BeginAnimation(property, animation);
}

不幸的是,如果调用 BeginAnimation(property,null) 的人删除了动画,则 Completed 事件似乎不会触发,因此在取消动画时我无法正确设置最终值。更糟糕的是我也无法删除事件处理程序......

有人知道如何以干净的方式做到这一点吗?

4

1 回答 1

1

看起来您正试图在动画结束后开始动画之前将值设置回初始值。如果您停止动画(或动画时间线结束时),这实际上会自动发生。在 WPF 中,动画可以看作是属性当前值之上的值叠加。停止或删除动画将删除覆盖,并且先前的值现在将再次开始显示。原始值没有丢失,只是暂时被遮蔽了。

通常,将属性显式设置回其先前值是不好的做法,因为如果最初未在对象上本地设置该值,则会产生内存开销。此外,这可能会在以后引入微妙的问题。例如,如果旧值是从样式派生的,则如果样式更改,属性将不再更改。

如果您仍然觉得必须提取当前值并稍后恢复它,请使用 ReadLocalValue() 而不是 GetValue()。如果该值未在本地设置,这将返回 DependencyProperty.UnsetValue。然后,您可以根据属性最初是否具有本地值,有条件地调用 ClearValue() 或 SetValue()。

于 2009-02-27T00:22:22.177 回答