Home of the AlmostImplementedException

WPF: How to use animations / animate a pie-chart

Modern applications use animations to create nice effects and shorten waiting times. In a pie-chart its also used to show the difference between values or for presentations.
To create such an effect we’ll again reuse the Pie-Class i created earlier and add the shadow effect to it.

With WPF its very easy to generate different animations with a little bit of code. For static animation we can declare a storyboard direct in XAML. Thats good for a loading or waiting screen. If you need to calculate values or want different animations, CodeBehind is your friend.

First we will animate the first Pie and draw it from 1° to 35° in 2 seconds to demonstrate how it is done.

First, we need a trigger to start the animation. Here, i do it right after the window is loaded. What you need to do is to create BeginStoryboard with a Storyboard and one or more Animation. I use the DoubleAnimation to change a double value over time. Storyboard.TargetName is the name of the control and Storyboard.TargetProperty is the name of the property we want to change. From and To should be clear enough.
Duration is the time we want for the animation. DoubleAnimation calculates how many step are needed to do it in 2 seconds.
And finaly we have BeginTime. Here you can set the waiting time for the animation before it starts. If you want to do multiple animation, one other another, then have to set the BeginTime to the time the previous animation is finished.

When we run this code nothing happens. More accurate we don’t see something happening. Thats because the Pie-Class don’t notify the UI about the changes. To correct this behaviour, we have to change the Angle-Property to a DependencyProperty.

In the Pie-Class we’ll remove the line public double Angle { get; set; } and replace it with the following code:

The first line creates a DependencyProperty. More details will follow in an extra post. For now its enough to know that a dependency property can set FrameworkPropertyMetadata. There we tell the compiler that every change of Angle causes a redraw.

The getter and setter are change to use the DependencyProperty as well. And if you execute the code now, you will see the animation. A DoubleAnimation (and any other Animation too) gives you a few more options to get the result you want. Maybe you want your animation to go foward and then backward. For this you have to set AutoReverse = “True”. Or maybe it should be play infinitly, then you have to set RepeatBehavior = “Forever”.

Thats very easy and very limited. If you want to create an animated PieChart that others can use, you can’t set the animation to like that. The solution is to use code behind to set the values.

This code just do the same thing as the XAML-code above. But now we can calculate a few values. Lets write a method that create a pie and do the animation for each pie after the other have finished.
First, create a new WPF-Window, add a canvas with the name “canvas” and add the DropShadowEffect to it. Then copy the following code to the class.

In the Main-Method we create a storyboard and call the new CreatePie-Method 3 times with 3 different colors. In CreatePie we create a Pie class and set all the values. The Angle is set to 0 because we want to animate the angle. In rotation we add all previous angles to get the rotation for the next pie-piece.
To get the desired effect to draw each pie after another, each pie have to wait. For this we set the BeginTime.
Run the code and see for your self…
As you may have noticed, each pie draws a single black line where it starts. To get rid of that we have to add 2 simple lines to the Pie-Class.

Now the animation is quite nice and we have a pie-chart that can be generated with as many pieces you may want. And to show you that you can change the animation, just comment the line myDoubleAnimation.BeginTime = … out of the code and all pies are now drawed at the same time.

Share :

, ,

Leave a Reply

Your email address will not be published. Required fields are marked *