Mar 29 2007
Big day yesterday. First we had a training session in the morning, and talked about animations. I could see how I got a few things wrong. Animations in XAML are very straightforward to create and start, and it gets a bit more complex when you want to control them and especially stop them. In my ColorClock, I’ve been confronted to a few of these problems: How to release the animation’s “grasp” on the dependency property it just animated? How to “chain” animations, making sure that they are correctly released so that they can eventually be garbage collected? How to synchronize animations? That’s where Josh’ practical experience really helps! Here are a few tips:
- To synchronize animations can be important to enhance the application’s visual appearance. Simple example: If you have a list of buttons, with one of them flashing (for example with an opacity animation, or a color animation). If you start flashing another of these buttons, it’s going to look ugly if they don’t flash together. However, there is no way to do that simply in XAML, and a solution would involve fairly complicated code-behind.
But that can be simplified: Create a controller class with a DependencyProperty (DP), and animate that property. Now, to flash the buttons, simply bind the opacity (or color…) to that controller’s DP. Since there is one animation only, and the rest is binding, the synchronization is automatic. Got to prototype that.
- When an animation is finished, it will by default keep the animated DP to the “To” value of that animation. Any attempt to modify that DP in code, or by actuating a control will fail. In fact, the animation will instantly set the DP’s value again to the “To” value. Here’s an example: In the ColorClock, I animate the Clock’s opacity at startup, to create a smooth appearing effect. However, the user can later modify that opacity using a slider. In order to allow that, I went the complicated way, which involved the “Remove” method of the Storyboard.
However, a much better way to do that is very simple too: The animation has a FillBehavior property! This property has two possible values: HoldEnd (default), which keeps the DP under the animation’s control even after it’s finished, and Stop, which will release the DP to its default value. So reaching the desired effect for the ColorClock should be as simple as setting that property to Stop, and thus simplify the code greatly.
- Removing a completed animation from a storyboard is not very intuitive. In the ColorClock, I have acted at the Storyboard level, which implies keeping a reference on the currently executing Storyboard, calling the “Remove” method, then creating a brand new Storyboard, adding animations to it, etc… That complicates the code, because it prevents the use of the simpler BeginAnimation method, where the Storyboard is created by the framework without us having to do it explicitly.
Well, here’s the trick: TO remove an animation, simply use the BeginAnimation method with the second parameter “animation” set to null! Damn, that’s easier.
myControl.BeginAnimation( RotateTransform.AngleProperty, null );
- Chaining/composing animations is affected by a bug, which may cause memory leaks and performance problems: Normally, when an animation is finished, it is disposed. However, a bug in the current implementation of WPF causes the animation to not be removed when HandoffBehavior is set to “Compose”. To solve that, the Completed event of the animation must be handled, and the animation removed manually using the code above. In order to make that more automatic, a controller class can be created quite easily. Simply add the starting animation to the controller, and let it handle the Completed event, removing the Animation after it’s finished.
Afternoon at Microsoft
In the afternoon, we had a “field trip” to Microsoft, about one hour drive from Tacoma. We met a few very interesting people there, who are going to help us (and have helped us already) to understand the best options for the communication model of our next application. I can’t give too many details about that, but it opened perspectives for us. What we’re exactly going to be able to do with it is not clear for the moment (we’re not only dealing with technical problems here). Anyway. It was nice to actually meet these people face to face, and it was nice to feel their commitment to help us. That’s really appreciated, and that’s going to be very useful!
We then went to the Microsoft shop and museum, for a moment of pure geekiness. I got myself a great sweater with a small Microsoft logo on the front, it really looks great.
Evening at the Needle
After leaving Microsoft, we headed to Seattle, a very scenic drive! The region is really beautiful, especially given the amazing weather! Yes, sun, blue sky, nice temperatures! The bay and Mount Rainier looked fantastic.
After a small walk around the tower, and a razzia on the souvenir shop for my wife, my girls and me, we went up to the observation deck, and enjoyed the sunset and the view… And then, one floor down, a great dinner in the revolving restaurant!!
The drive back was nice too, with a short and unexpected visit of Seattle-by-night (wrong turn ;) but we found our way back soon enough!
On a personal note, I am really missing my girls, so here’s a pic of them!