Как получить Storyboard.Target, если цель была установлена ​​с помощью Storyboard.SetTargetName? - PullRequest
1 голос
/ 10 марта 2012

Почему: я пытаюсь реализовать расширение для Storyboard (или, в более общем случае, TimelineGroup), которое можно запустить после Storyboard. Завершено, чтобы «разблокировать» анимированные свойства и оставить их на новом значении (довольно тупой обход см. свойство блокировки логической анимации для фона).

Таким образом, приведенное ниже расширение предоставляет единый способ сделать это, вместо того, чтобы пытаться отслеживать каждое измененное свойство и то, каким было ожидаемое значение.

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 возвращает ноль, если не использовался Storyboard.SetTarget. Но когда целью является не UIElement (например, когда это ScaleTransform), SetTarget приведет к сбою анимации. Вместо этого (и не в дополнение) должен использоваться Storyboard.SetTargetName. Смотрите эту проблему: Storyboard.SetTarget vs Storyboard.SetTargetName . Итак, у нас есть уловка-22 - есть ли другой способ извлечь Storyboard.Target (и не только его имя) из анимации?

Я знаю, что могу использовать несколько анонимных методов по мере создания анимации, чтобы я знал, с каким объектом я имею дело, но это было бы намного чище.

...