Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Apply Animation Concurrently on Multiple Controls

0.00/5 (No votes)
13 Jun 2012 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. 

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.  

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. 

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here