Creating new animation types
It’s a fairly uncommon scenario to want to animate a type that’s not already built into WPF. But when you do, it takes quite a lot of work, mostly hacking it with Reflector to explore this undocumented venue.
One day I needed to animate the CornerRadius of a Border. Don’t ask me why, it just happened. I was a bit surprised to find out that almost all animations have the (almost) exact same implementation, but no code was shared. Meaning, if you had to create a new one, all the code would have to be copied.
All animations inherit from AnimationTimeline. Each one has a base class TAnimationBase, and a few possible implementations: TAnimation (a linear animation), TAnimationUsingKeyFrames and (the more rare) TAnimationUsingPath. Note the T. Does it remind you of something? If you said “generics”, you were right. I may be overlooking something, since WPF is such a vast framework, whose designers must have had a much broader view to make such decisions, but I think this could have been implemented a bit better. Here’s how.
When I wrote a paper about CLR generics for my university, I stumbled upon a problem some of you may have also encountered: How can I use arithmetic operators on a generic type? In C++ it’s rather easy: the compiler checks the template by call when it performs the macro-expansion. So if you write:
template<class T> class MyClass
{
T MyMethod(T a, T b) { return a + b; }
}
That would compile just fine. It would only throw compilation errors when you try to instantiate MyClass<T> where T doesn’t support the “+” operator. In C#, you simply can’t do that (unless you use casting and a lot of ifs – an ugly solution), since you can only constrain using interfaces and base classes. Because numeric types have no such common ancestor, you’re in a pickle.
Anders Hejlsberg has lectured about a possible solution for this issue: create a calculator class. I shall demonstrate using the calculator interface I created for the animation:
public interface IAnimationCalculator<T>
where T : struct
{
T Add(T value1, T value2);
T Subtract(T value1, T value2);
T Scale(T value, double factor);
T Interpolate(T from, T to, double progress);
T GetZeroValue(T baseValue);
double GetSegmentLength(T from, T to);
bool IsValidAnimationValue(T value);
}
I constrained T to be a value type. I assumed most of the types we’d like to animate are lightweight structures, but this restriction can be removed. And so, I created the other classes, according to the scheme I mentioned above:
Implementers have very few things to do: create an IAnimationCalculator for their type, inherit from the desired classes, override the abstract methods (very few and usually freezable-related, and of course the CreateCalculator() method) and add constructors (just call the ones from the base.) In the attached project you’ll find a sample implementation for the CornerRadius type.
One last caveat: I did not test this on a type other than CornerRadius. It’s quite possible this small framework will not fit every scenario. As I said, the designers of WPF may very well have had a good reason not to take this approach.
Update: I’ve changed the implementation from a calculator type parameter to a CreateCalculator() abstract method. This makes my classes slightly more cumbersome, but more importantly, makes writing polymorphic code a lot nicer (consider writing a method that accepts a LinearAnimationBase. Why should you have to drag along that TCalc type parameter?)
3 Responses to Creating new animation types
Tags
.NET 4 Animation Async Axum Blog C# ClearType Cloud CLR CodeValue Contests Deep Zoom Experiments Generics Google Ink Lectures Modeling Personal Pivot Prism Programming Languages Prolog Reflector RTL Sela Silverlight The Arbel Network Themes Threading Tips Visual Studio WCF Windows 7 Windows 2003 Windows Azure Windows Forms Windows Phone Windows Vista Windows XP WPF XAML ZuneArchives
- June 2011
- November 2010
- August 2010
- July 2010
- June 2010
- March 2010
- December 2009
- November 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- November 2007
- September 2007
- June 2007
- May 2007
- February 2007
- November 2006
- October 2006
- February 2006
- August 2005
- February 2005
- August 2004
- July 2004
- June 2004
- May 2004







During my experiments with WPF, I sometimes encountered a recurring operation that required too much
Hello,
I just had the same problem: there was a need for an animated CornerRadius. You can imagine how happy I was as I found your site…
Just a few words: OUTSTANDING!! and many thanks.
Sven
Thanks, glad to hear it was helpful.