views:

27

answers:

2

Given a Storyboard started by the VisualStateManager as part of a ControlTemplate, how would I adjust the SpeedRatio of that animation based on property changes of the control?

<ControlTemplate>
  <Grid>
    <VisualStateManager.VisualStateGroups>
      <VisualStateGroup>
        <VisualState>
          <Storyboard Name="SpinningThing"
                      SpeedRatio="{Binding SpinningSpeedRatio}">
            ...

This needs to work in both WPF and Silverlight.

I don't think I can set a binding there for a number of reasons. Foremost, Storyboard is Freezable so you can't just go setting the SpeedRatio all willy-nilly in WPF. But, if it's started by the VisualStateManager, can I call SetSpeedRatio on it?

Also, since its parent is a VisualState, doesn't that mean there would be no governing FrameworkElement to relate to for it?

So, if I can't do it with a binding, how can this be done?

A: 

Normally you would use a {TemplateBinding...} rather than a {Binding...}, but that only works for simple, compatible, types.

You should also be able to bind to the templated control using a "relative binding source". This also allows you to use a value convertor if the types do not match.

SpeedRation={Binding SomeProperty, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource SomeConverter}}" 

I have not tested this in WPF, but Silverlight is normally the feature-restricted one.

Enough already
Unfortunately, WPF is where the simple answer falls apart. In WPF, timelines are Freezable objects, so a binding will not change the actual value of the SpeedRatio. http://msdn.microsoft.com/en-us/library/system.windows.media.animation.timeline.aspxAlso, because it is in a ViewState (I guess), you get the binding error saying "Cannot find governing FrameworkElement for binding...".
MojoFilter
A: 

Alright, so it looks like there really is no way to handle this strictly with a binding. So to account for it, I have hooked events in the code-behind to start/adjust the animations as appropriate.

MojoFilter