When I started the Metro In Motion series, I thought I would probably post three or four articles and be done. However, every time I use my Windows Phone 7 I seem to spot a new 'native' fluid UI effect which I would like to use in my own code. Also, these posts have proven very popular, there appears to be a real developer 'need' for this sort of information.
In this instalment of Metro In Motion I will show how to implement the fluid auto-complete effect that can be seen in the Windows Phone 7 email client. You can see a 'storyboard' for this effect below; the items within the auto-complete popup slide gracefully into view when the popup initially renders:
This effect uses the
AutoCompleteBox which is part of the Silverlight for Windows Phone Toolkit. I have implemented this effect as a Blend Behaviour, allowing it to be easily added to an AutoCompleteBox either via drag and drop within Expression Blend, or by simply adding the XAML below:
Let's take a look at how this behaviour is implemented ...
In order for this effect to work, we need to handle the
Opening event raised by the
Popup control that is part of the
AutoCompleteBox template. When this event fires, each of the elements within the
ListBox that the
Popup contains are animated. The first task is to locate the
ListBox and the
Popup, this is performed when the behaviour is attached:
The above code uses some simple Linq-to-VisualTree to locate these elements. Notice that the approach taken first tries to locate these elements, if this fails, the
Loaded event is handled, which is fired when elements (and their template components) are added to the visual tree.
The animation is fired each time the
Popup is opened. Creating the animation itself is quite simple, the items within the
ListBox are iterated over, with a
TranslateTransform created for each, with delayed
Storyboard animations used to fire the animations sequentially. However, the container's (i.e.
ListBoxItem instances) may not have been created when the
Opened event fires. In order to handle this, the code below checks for the container of the item at the first index. If this container has not yet been generated, the code which creates the animations is deferred until after the next
LayoutUpdated event. This should ensure that the containers are now present. The code is shown below:
The full sourcecode for this behaviour can be found in the WP7Contrib project, within the
You can download a simple working example here: MetroInMotionEight.zip
I have of course updated the Sandwich Flow, Metro In Motion demo application to include this effect. Again, this is available via the WP7Contrib project: