原因:我正在尝试实现Storyboard(或更普遍的TimelineGroup)的扩展,可以在Storyboard.Completed之后运行以“解锁”动画属性,并将它们保留为新值(这是一个愚蠢的解决方法)本身,请参阅Boolean Animation locks property了解背景信息。)
因此,下面的扩展提供了一种统一的方法,而不是试图跟踪每个属性的变化。预期的价值结果如何。
public static void ReleaseAnimatedProperties(this TimelineGroup storyboard) {
foreach (Timeline anim in storyboard.Children) {
// This is null unless Storyboard.SetTarget(anim, <animatable>) has been called
Animatable animatable = (Animatable)Storyboard.GetTarget(anim);
PropertyPath path = Storyboard.GetTargetProperty(anim);
DependencyProperty dp = (DependencyProperty)path.PathParameters[0];
animatable.SetValue(dp, animatable.GetValue(dp)); // Set it to what it ended up as
animatable.ApplyAnimationClock(dp, null); // Drop the "locking" on the animated property
}
}
什么:如何检索Storyboard.Target?
Storyboard.GetTarget返回null UNLESS使用了Storyboard.SetTarget。但是当目标不是UIElement时(例如当它是ScaleTransform时),SetTarget将导致动画失败。相反(而不是另外)必须使用Storyboard.SetTargetName。请参阅此问题:Storyboard.SetTarget vs Storyboard.SetTargetName。所以我们有一个catch-22 - 有没有其他方法从动画中提取Storyboard.Target(而不仅仅是它的名字)?
我知道我可以在构建动画时使用一堆匿名方法,这样我就知道我正在处理哪个对象,但这会更加清晰。