SpeedRatio BUG?? - OK I'll Try this again
-
jeudi 7 septembre 2006 14:12
I am animating the SpeedRatio of animation A with animation B. The speed of animation A does not change. If I attach a current time invalidated handler and look at the speed ratio values I can see that they are changing but the animation is not affected. If though I read the speed ratio value and set it right back with SetSpeedRatio() things work.
Is this a bug or intended behavior?
I thought animations were at the top priority when DP's are being written.
I would prefer not to do the extra bookkeeping of the CTI handlers as we can have a lot of things going on and may not know we need to do this (animate sr) till after the fact. I do not want to attach CTI to everything.
Would appreciate a reply...
Toutes les réponses
-
jeudi 7 septembre 2006 16:31
Animating, databinding, or otherwise modifying a property of an animation doesn't have any effect after the animation has been started. Once an animation or other timeline has been started (for example with BeginStoryboard or BeginAnimation), clocks are created to control the animation, and those clocks have a copy of all the data from the original timeline. So updates to the timeline aren't reflected in the clock. There's more info in the SDK here, under the heading "Databinding and Animating Timelines".
The Storyboard.SetSpeedRatio method works because it knows how to find the clock and modify its speed ratio. But note that that method modifies the SpeedRatio of the clock, not the Storyboard.SpeedRatio property itself.
The SetStoryboardSpeedRatio trigger action is another way to modify the speed ratio, and one that's available from Xaml. But that's a discrete change, not an animated one like you're looking for.
One way I can think of to do what you're after is manually via the CurrentTimeInvalidated handler, as you tried. To determine if the timeline's SpeedRatio is being animated, you can call DependencyPropertyHelper.GetValueSource on the timeline for the Timline.SpeedRatioProperty; if it returns ValueSource.IsAnimated,
-
jeudi 7 septembre 2006 16:33
(Sorry, somehow that posted itself mid-edit. Completing the last paragraph ...)
One way I can think of to do what you're after is manually via the CurrentTimeInvalidated handler, as you tried. To determine if the timeline's SpeedRatio is being animated, you can call DependencyPropertyHelper.GetValueSource on the timeline for the Timline.SpeedRatioProperty; if it returns ValueSource.IsAnimated, then you could use that as an indication to your handler that you should call SetSpeedRatio.
-
jeudi 7 septembre 2006 18:49
Thanks Mike.
I appreciate your response. I find it interesting that for some properties there are 'special' functions that intercede the normal flow of things. SetSpeedRatio() seems to be one of them. Not very many DP's have these circumventing functions. Though not exactly the same thing, on one of my trips to MS over the summer someone told me that SeekAlignedToLastTick(...) was put in special to handle a need that Seek() could not.
Personally I find history helps to understand. So no response required, but I'd like to know what it was that caused SetSpeedRatio() to come into existance. As I said, if most DP's do not have these overrides, then why do the ones that do, do.
Thanks
Ted
-
vendredi 8 septembre 2006 22:44
Despite the implication of some of the names here, this isn't circumventing the normal DP patterns.
The issue here is that Storyboard.SpeedRatio and Storyboard.SetSpeedRatio(FrameworkElement,double) operate on two different values. Storyboard.SpeedRatio is a property on Storyboard that is backed by a DP, and follows the usual DP pattern. Storyboard.SetSpeedRatio modifies the SpeedRatio property of a different object (a Clock). Or in the spirit of pseudo-code saying more than a thousand words, the implementations look something like this:
class Storyboard
{
...
public double SpeedRatio
{
get { return GetValue( SpeedRatioProperty ) as double; }
set { SetValue( SpeedRatioProperty, value ); }
}
...
public void SetSpeedRatio( FrameworkElement containingObject, double speedRatio )
{
Clock clock = GetStoryboardClock( containingObject );
clock.Controller.SpeedRatio = speedRatio;
}
...
}The clock here that SetSpeedRatio finds is the one that is created during a BeginStoryboard.
And you're right that Storyboard.SeekAlignedToLastTick similarly finds a clock, and calls clock.Controller.SeekAlignedToLastTick(...).

