WPF – Animating multiple elements simultaneously

A question appeared on StackOverflow asking how to animate a property on multiple elements from one or more trigger mechanisms (i.e. a button click or list box selection).  The traditional approach (for brevity’s sake, I omitted the Xaml comprising the actual UI elements) is rather straight-forward:

<Window.Resources>
    <Storyboard x:Key="OnClick1">
        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                                       Storyboard.TargetName="textBlock1" 
                                       Storyboard.TargetProperty="(UIElement.Opacity)">
            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
            <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                                       Storyboard.TargetName="textBlock2" 
                                       Storyboard.TargetProperty="(UIElement.Opacity)">
            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
            <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                                       Storyboard.TargetName="textBlock3" 
                                       Storyboard.TargetProperty="(UIElement.Opacity)">
            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
            <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                                       Storyboard.TargetName="textBlock4" 
                                       Storyboard.TargetProperty="(UIElement.Opacity)">
            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
            <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>

    <Window.Triggers>
        <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button">
            <BeginStoryboard Storyboard="{StaticResource OnClick1}"/>
        </EventTrigger>
    </Window.Triggers>
</Window.Resources>
The major complaint about the above solution is the repetition of the Animations.  Since each TextBlock implements the same animation, an easier to maintain solution would be ideal.  Initially, I believed a Xaml-only solution would not be possible, but StackOverflow user, kek444, put me onto a simple trick of animating a single value and DataBinding the TextBlocks to it.  While his solution involved setting the DataContext on an element, I believe using a placeholder element is a cleaner approach (however, I’m sure this is open to debate).
The updated version of the above Xaml would look as follows:

<Window.Resources>
<UIElement x:Key=”AnimationPlaceholder” Opacity=”0″/> <Style TargetType=”TextBlock”>
<Setter Property=”Opacity”
Value=”{Binding Source={StaticResource AnimationPlaceholder}, Path=Opacity}” />
</Style>

<Storyboard x:Key=”OnClick1″>
<DoubleAnimationUsingKeyFrames BeginTime=”00:00:00″
Storyboard.Target=”{StaticResource AnimationPlaceholder}”
Storyboard.TargetProperty=”(UIElement.Opacity)”>
<SplineDoubleKeyFrame KeyTime=”00:00:00″ Value=”0″/>
<SplineDoubleKeyFrame KeyTime=”00:00:00.5000000″ Value=”1″/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>

<Window.Triggers>
<EventTrigger RoutedEvent=”ButtonBase.Click” SourceName=”button”>
<BeginStoryboard Storyboard=”{StaticResource OnClick1}”/>
</EventTrigger>
</Window.Triggers>
</Window.Resources>


 

In this snippet, I’m using a UIElement to hold the animation value since it supports the Opacity property (but in fact, any property of type double, would suffice).  Also, if you’re not adverse to a little coding, a custom class could be created to contain the values you wish to change for a particular animation.  A style is created to affect all TextBoxes, but this can easily be modified to use explicit styling.  Finally, the Storyboard targets the placeholder object and changes its value from 0 to 1 over 0.5 seconds.  The style uses DataBinding to bind its Opacity property to the placeholder’s.

Though Blend creates a lot of the Xaml for you when creating trigger-based animations, sometimes the result can be less than ideal.  Additionally, as I’ve had reinforced through this little exercise, there is more than one way to skin a cat when it comes to Xaml, so please feel free to comment with refinements or alternative solutions.

Sergio Loscialo

View Comments

  • Hi,
    The given tutorial is very useful to commonly apply the style to TextBlock using animation.
    Having one more question. Can we fade out the the TextBlock again using the same style.
    It seems given style is static. we cannot change the opacity of UIElement again back to 1.0 or some thing else.
    The Storyboard is not changing the opacity with it's duration due to static resource.
    Could anyone please share an idea to resolve the issue.
    Thanks in advance.
    -Jaya

  • Hi,
    The given tutorial is very useful to commonly apply the style to TextBlock using animation.
    Having one more question. Can we fade out the the TextBlock again using the same style.
    It seems given style is static. we cannot change the opacity of UIElement again back to 1.0 or some thing else.
    The Storyboard is not changing the opacity with it's duration due to static resource.
    Could anyone please share an idea to resolve the issue.
    Thanks in advance.
    -Jaya

Recent Posts

8-Step AWS to Microsoft Azure Migration Strategy

Microsoft Azure and Amazon Web Services (AWS) are two of the most popular cloud platforms.…

1 day ago

How to Navigate Azure Governance

 Cloud management is difficult to do manually, especially if you work with multiple cloud…

1 week ago

Why Azure’s Scalability is Your Key to Business Growth & Efficiency

Azure’s scalable infrastructure is often cited as one of the primary reasons why it's the…

3 weeks ago

Unlocking the Power of AI in your Software Development Life Cycle (SDLC)

https://www.youtube.com/watch?v=wDzCN0d8SeA Watch our "Unlocking the Power of AI in your Software Development Life Cycle (SDLC)"…

1 month ago

The Role of FinOps in Accelerating Business Innovation

FinOps is a strategic approach to managing cloud costs. It combines financial management best practices…

1 month ago

Azure Kubernetes Security Best Practices

Using Kubernetes with Azure combines the power of Kubernetes container orchestration and the cloud capabilities…

2 months ago