1

The why: I am trying to implement an extension for Storyboard (or more generally TimelineGroup) that can be run after Storyboard.Completed to "unlock" the animated properties, and leaving them at their new value (quite a goofy workaround in itself, see Boolean Animation locks property for background).

So the extension below provides a uniform way of doing this rather than trying to keep track of each property changed & what the value was expected end up as.

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

    }

}

The what: How can I retrieve the Storyboard.Target?

Storyboard.GetTarget returns null UNLESS Storyboard.SetTarget was used. But when the target is not a UIElement (for instance when it is a ScaleTransform), SetTarget will cause the animation to fail. Instead (and not in addition) Storyboard.SetTargetName must be used. See this issue: Storyboard.SetTarget vs Storyboard.SetTargetName. So we've got a catch-22 - is there any other way to pull out the Storyboard.Target (and not just its name) from an animation?

I'm aware I can tack on a bunch of anonymous methods as the animation is built, so that I know which object I'm dealing with, but this would be so much cleaner.

Community
  • 1
  • 1
Josh Sutterfield
  • 1,943
  • 2
  • 16
  • 25

0 Answers0