MINI SUPPORTERS:

 

 

Modifying Animations using C# - Page 5
       by kirupa  |  14 May 2008

In the previous page, we drilled through our XAML using C#, found the elusive KeyTime property, and set its value depending on what our incrementer value was. Yet, when you ran the animation, nothing happened. What gives?

Cannot Change Properties of a Running Animation
The heading should give it away on why even though you changed your KeyTime property's values, your animation's speed did not change. The reason is that properties of a running animation cannot be changed without you restarting the animation.

That means that any changes you make get queued, and when you restart your animation, those changes get applied. This means that you will need to add one more line of code:

private void ModifyAnimation(double incrementer)
{
Storyboard sb = this.FindResource("Oscillate") as Storyboard;
DoubleAnimationUsingKeyFrames animation = sb.Children[0] as DoubleAnimationUsingKeyFrames;
DoubleKeyFrameCollection keyFrames = animation.KeyFrames;
for (int i = 0; i < keyFrames.Count; i++)
{
SplineDoubleKeyFrame keyFrame = keyFrames[i] as SplineDoubleKeyFrame;
keyFrame.KeyTime = new TimeSpan(0, 0, (int)incrementer * i);
}
sb.Begin(this);
}

To restart your animation, you call the Begin method on your storyboard - which is sb in our case.

If you were to run your application this time, notice that changing the speed values in your combobox changes the speed of the circle's oscillation. For this type of animation, you are bound to see the jump where the ball skips to its starting location whenever you change the speed and the animation restarts.

You can work around that generally by setting a virtual keyframe at Time 0 where there is no keyframe that point:

[ normally, setting a virtual keyframe is a good way to stop the jump ]

The only problem is that this type of animation doesn't work well to virtual keyframes. There are many other types of animations that do work well, so you will have to experiment and figure out a way to prevent the jumping.

There are more complicated programmatic ways of preventing the jump, but I will save the discussion of that topic for a later time. Your final code for Window1.xaml.cs should be as follows:

public partial class Window1
{
public Window1()
{
this.InitializeComponent();
 
// Insert code required on object creation below this point.
}
 
private void ChangeSpeed(object sender, SelectionChangedEventArgs e)
{
double incrementer = 1;
 
ComboBox comboBox = sender as ComboBox;
ComboBoxItem selectedItem = comboBox.SelectedValue as ComboBoxItem;
 
string speed = selectedItem.Content.ToString();
 
if (speed == "Slow")
{
incrementer = 3;
}
else if (speed == "Normal")
{
incrementer = 2;
}
else if (speed == "Fast")
{
incrementer = 1;
}
 
ModifyAnimation(incrementer);
}
 
private void ModifyAnimation(double incrementer)
{
Storyboard sb = this.FindResource("Oscillate") as Storyboard;
DoubleAnimationUsingKeyFrames animation = sb.Children[0] as DoubleAnimationUsingKeyFrames;
DoubleKeyFrameCollection keyFrames = animation.KeyFrames;
 
for (int i = 0; i < keyFrames.Count; i++)
{
SplineDoubleKeyFrame keyFrame = keyFrames[i] as SplineDoubleKeyFrame;
keyFrame.KeyTime = new TimeSpan(0, 0, (int)incrementer * i);
}
 
sb.Begin(this);
}
}

And with that, you should be set! If you are curious to see how my implementation turned out, you can download the source final source files below:

Download Sample Project

Conclusion
Hopefully, this tutorial gave you an appreciation of how working between XAML and C# can actually save you a lot of time. What is nice about this is that you take advantage of quickly creating the framework of your animation - either manually or using a tool such as Expression Blend, and then manipulating the parts that you can't change easily in XAML using C#.

If you had to pick only C# or only XAML, the end result would be more difficult to achieve. The amount of C# code needed to, for example, define the TranslateTransform.X on your storyboard is not easy to figure out even with the XAML in front of you.

Being able to change the KeyTime value based on a combobox selection change is quite difficult (if not impossible) to do using just XAML. At the very least, you will need to write some code to create a ValueConverter to translate the Slow, Fast, and Normal values to the corresponding incrementer values.

Need Help?
If you have any questions related to what you saw in this tutorial or anything WPF, Silverlight, etc., please post in our Programming forum.


Need Help?

If you have questions, need some assistance on this topic, or just want to chat - please drop by our friendly forums and post your question. There are a lot of knowledgeable and witty people who would be happy to help you out. Plus, we have a large collection of smileys you can use

Share

Did you enjoy reading this and found it useful? If so, please share it with your friends:

If you didn't like it, I always like to hear how I can do better next time. Please feel free to contact me directly at kirupa[at]kirupa.com.

Cheers!

Kirupa Chinnathambi
about | facebook | twitter

 

1 | 2 | 3 | 4 | 5

SUPPORTERS:

cloud storage
cloud storage
kirupa.com's fast and reliable hosting provided by Media Temple. Creative web apps. Make your own free flash banners and photo slideshows.
HTML5 CSS3 Mobile Gallery for iPhone, iPad Flash effects. Art without coding.
Flipping Book - page flip flash component. Flash-Gallery.com - Get your flash photo gallery (flash component or swf gallery
X-Platform Application Development for Flash Free Flash Components Download - XML Templates, Players and Galleries.

two computer monitors

US Direct

Learn how to advertise on kirupa.com  
 
SHARE:



MINI SUPPORTERS: