Click here to Skip to main content
15,885,914 members
Articles / Desktop Programming / WPF
Tip/Trick

Apply Animation Concurrently on Multiple Controls

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
13 Jun 2012CPOL2 min read 10.6K   1  
Advanced technique to apply animation concurrently on multiple controls.

Introduction

When I worked on writing the Tetris game using Silverlight, I would like an animation happen before a qualified row of squares begin to collapse in response to a command. This will obviously make the game more fun. 

Image 1

The Problem

The animation should be invoked if necessary in a command handler (see the pseudo code below). I tried storyboard with multiple children and multiple storyboards, neither of them worked and this drove me nut. Searching the Internet, some one said this is impossible since there is only UI thread.  

C#
xxx_command() 
{  
     1. Check if rows qualified for collapse
     2. If yes, raise collapse event, do the animation here
     3. Collapse
}

But looking at windows operating system and games they all have animations. I believe a solution exists. Finally I found it. 

The Solution 

The solution turns out pretty simple. The animation in WPF itself is essentially a series of actions responding to a timer event. So I don’t need to use storyboard: simply initiate a dispatcher timer, hook up an anonymous delegate handler, inside which the rows of squares are iterated and opacity is reduced gradually. 

There are two tricky points here. First, it needs to disable all other commands such that only animation is executed in the UI thread. Second, it needs to return to the code right after the animation (line 3, Collapse). To address the first issue, introduce a new variable AnimationInProgress. If this variable is true all command handlers will simply skip including the keyboard handlers. To address the second issue, we need to use anonymous delegate and wrap all the code after the animation into a delegate parameter. 

C#
collapse_event_handler(Action<object> collapseAction)
{
    AnimationInProgress = true;
    var timer = new DispatcherTimer();
    timer.tick += delegate{
                Code to iterate all squares and reduce opacity
                If (done)
                {
                    collapseAction();
                                        timer.Stop();
                                        timer = null;
                                        AnimationInProgress = false;
                                }
            };
    timer.Start();
}

Points of Interest

Note that the key to the solution is using anonymous delegate to mimic returning to the command. Anonymous delegate is a closure that contains the entire execution context. In C/C++, it is function pointers. Looking in this perspective it is not surprising that why windows operation system and games can implement animations with ease. 

Demo 

You can go to http://www.bizsoftzen.com/silverlight-demos to see the demo. When a row is qualified for collapse they are faded gradually(opacity is decremented gradually). 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --