3

I have the following code:

<Color x:Key="SelectedColor">Gold</Color> 

And a TabItem Style that contains the color

<VisualState x:Name="Selected">
    <Storyboard>
        <ColorAnimationUsingKeyFrames 
            Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)"
            Storyboard.TargetName="InnerRectangle2">
            <EasingColorKeyFrame KeyTime="0" Value="{DynamicResource SelectedColor}"/>
        </ColorAnimationUsingKeyFrames>

It turns out I can't use a DynamicResource on an EasingColorKeyFrame.
What can I do to achieve my effect?

I need to set the color dynamically, so just swapping "{DynamicResource SelectedColor}" with "{StaticResource SelectedColor}" is off the table.

I've created a tiny solution to demonstrate the problem - the Selected Tab should be Gold colored, but it's actually transparent, because I guess the VSM can't resolve the color named "SelectedColor"

http://dl.dropbox.com/u/10557283/DynamicBug.zip

akjoshi
  • 15,374
  • 13
  • 103
  • 121
patrick
  • 16,091
  • 29
  • 100
  • 164

4 Answers4

6

Animations(VSM) are freezable objects. As soon as you set a binding on a dependency property of a Freezable, you prevent the Freezable from being frozen. Thus, the bindings on the Value property of your EasingColorKeyFrame objects are preventing the storyboards from being frozen.

As a way out you can try any these three approaches whichever suits you best -

  • Try declaring the resource as StaticResource and use it in your VSM. StaticResource explanation for VSM

  • What i understand from your code is you want the selected tabItem in golden color. So, as a workaround you can do is have the two borders contained in a panel say grid one over other with golden border default visibility as collapsed and normal one visible. Now, on selected event (on property change of IsSelected or whatever aproach) of your tabItem you can swap the visibility of two borders giving the same effect. Of course this workaround is specific to this case, for example it only makes sense if the EasingColorKeyFrame key time is 0, otherwise it doesn't give the same visual effect.

  • Lastly, if you want to stick to do it through animation, you can achieve this in code behind. These posts might proves helpful to you - Woakaround for dynamicResource in Animation, Animation in code behind and Setting foreground with VSM

Community
  • 1
  • 1
Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
  • Gold is just the default color, I want it to be dynamically set. I think this rules out the first two points. Still thinking about the third. – patrick Jul 23 '12 at 21:42
3

It's because the VSM types aren't part of the logical tree, so the dynamic resource lookup cannot be resolved.

Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393
  • @iterationx: use StaticResource. – Phil Apr 26 '12 at 18:26
  • @Phil I want to change the colors at runtime – patrick Apr 26 '12 at 18:29
  • move EasingColorKeyFrame to resources outside VSM, reference color as dynamic resource and reference EasingColorKeyFrame in ColorAnimationUsingKeyFrames as static resources. something like this must work – koshdim Apr 30 '12 at 12:46
  • @koshdim How can I move EasingColorKeyFrame? ColorAnimationUsingKeyFrames does not have a Value property, usually I would do a Value={StaticResource X}" , but I can't do that in this case? – patrick Jul 23 '12 at 15:04
2

I figured out a way to do it with layers. Make multiple copies of your object, and then just modify the transparencies like this:

<VisualState x:Name="Selected">
    <Storyboard>
        <DoubleAnimation Storyboard.TargetName="InnerRectangleBorder"
                         Storyboard.TargetProperty="Opacity"
                         To="0"
                         Duration="0:0:0" />

        <DoubleAnimation Storyboard.TargetName="InnerRectangleBorderMouseOver"
                         Storyboard.TargetProperty="Opacity"
                         To="0"
                         Duration="0:0:0.5" />

        <DoubleAnimation Storyboard.TargetName="InnerRectangleBorderSelected"
                         Storyboard.TargetProperty="Opacity"
                         To="1"
                         Duration="0:0:1" />
    </Storyboard>
</VisualState>
Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68
patrick
  • 16,091
  • 29
  • 100
  • 164
0

I realize this is a bit late, but this example worked very well for me regarding assignment of a color using a DynamicResource in a VisualState Storyboard:

<VisualState x:Name="PopupOpen">
  <Storyboard>
        <ObjectAnimationUsingKeyFrames
               Storyboard.TargetName="rootGrid"
               Storyboard.TargetProperty="(Panel.Background)">
            <DiscreteObjectKeyFrame KeyTime="0:0:0.25" Value=" 
            {DynamicResource 
                  BrushIconComboBox_Popup_Open_Background}" />
cpdev
  • 27
  • 4