Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Synchronize WPF ColorAnimation across several controls

I have several toggle-like buttons that I want to pulsate in unison when in the pressed state.

I have defined a style with a trigger that kicks-off the glow animation and this works just fine, apart from the fact that each button pulsates asynchronously from the others.

How can I have each button synchronize its pulse to the others?

Here's the style:

<Storyboard x:Key="pulseStory">
    <ColorAnimation                                                                    
        Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)"
                    From="Red"
                    To="Transparent"
                    Duration="0:0:1" />
</Storyboard>

<Style x:Key="pulseButton" TargetType="Button">
    <Style.Triggers>
        <DataTrigger Binding="{Binding Tag,RelativeSource={RelativeSource Self}}" Value="True">
            <DataTrigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource pulseStory}"/>
            </DataTrigger.EnterActions>
        </DataTrigger>
    </Style.Triggers>
</Style>

Cheers!

like image 300
Florian Doyon Avatar asked Jan 18 '11 15:01

Florian Doyon


2 Answers

OK ... I'll take a stab at this one ...

The WPF framework doesn't have any facility for synchronizing animations that are running concurrently, so you are going to have to come up with a different method. One idea springs to mind ...

Animate some Color property of a hidden UI element within your storyboard, then use UI binding (i.e. ElementName bindings) to connect to the Color of each of your buttons to this hidden UI element.

like image 77
ColinE Avatar answered Sep 22 '22 11:09

ColinE


Actually you should be doing this via a resource, at least using a hidden control is a bit too much of a hack for me personally.

What needs to be met for it to work:

  1. The property you bind to needs to be a DependencyProperty, hence your enveloping object needs to be a DependencyObject.
  2. You have to reference the object as a static resource (as opposed to a dynamic resource) like this:
<DoubleAnimation
    Storyboard.Target="{StaticResource AnimationValue}"
    Storyboard.TargetProperty="(local:WrappedValue.Value)"
    To="0" Duration="0:0:1"/>

Well, admittedly it's a bit hacky as well to have a Wrapper-class for this but it's cleaner than a full control (if you want to use controls you can utilize some unused Tag-property, e.g. of the container that hosts all your controls)

like image 35
H.B. Avatar answered Sep 21 '22 11:09

H.B.