Charles Petzold



Text-Morphing CheckBox Template for Silverlight

January 9, 2009
Utica, New York

My Wednesday blog entry demonstrated a Silverlight class named PointCollectionInterpolator that interpolates between two sets of points based on an animatable Progress property. As a demonstration of this interpolation, I've been using two PointCollection objects that spell out the words "No" and "Yes" in a simple script stroke font:

My real goal was to incorporate this technique in a template for a CheckBox control, like I did for a WPF CheckBox in an MSDN article two years ago.

And therein lies a problem: PointCollectionInterpolator is designed to be instantiated as a resource, which allows for both a binding to be defined on a Polyline element, and the Progress property to be animated. But templates in Silverlight do not have local resources. A template can reference resources defined outside the template, but the animations in the template are local to the template, and thus can't touch external resources.

My solution to this quandary was to define a wrapper class for PointCollectionInterpolator derived from UserControl. This wrapper class I called InterpolatedPolylineControl and here's the XAML part:

The control has an embedded Polyline with a binding to the PointCollectionInterpolator resource. This is not quite the same PointCollectionInterpolator from Wednesday's blog entry: I added a Transform property of type Transform.

The C# code file for the InterpolatedPolylineControl class isn't very interesting. Like PointCollectionInterpolator, InterpolatedPolylineControl defines properties named Points1, Points2, Progress, and Transform. When these properties change, the control transfers their values to the corresponding properties in the PointCollectionInterpolator resource. InterpolatedPolylineControl also defines properties named Stroke and StrokeThickness, and when these properties change, the control transfers their values to the corresponding properties in the embedded Polyline.

The advantage of the InterpolatedPolylineControl is that you can use it in a CheckBox template:

WPF programmers accustomed to using Trigger objects in the template will have to become familiar with the Silverlight VisualStateManager, which performs much of the same functions, including initiating animations. A CheckBox referencing this template can be defined like so:

You can download all the source code — besides the two custom classes, everything else I've done is in Page.xaml — and try it out here:

TextMorphCheckBoxDemo.html

It's a CheckBox so click on it!

You'll notice that the CheckBox gets larger as the text morphs from "No" to "Yes" because the size of the control is based on the size of the embedded Polyline inside the template, and the "No" and "Yes" polylines are different sizes. If this is undesirable, setting explicit Width and Height properties on the CheckBox will override the content size in determining the dimensions of the control.

Much worse was an earlier version that didn't include the Transform property in the PointCollectionInterpolator and InterpolatedPolylineControl classes, and instead relied on the RenderTransform property of Polyline to increase the size of the text: Because RenderTransform affects only the rendered visual of the element and does not affect layout, the CheckBox sized itself based on the untransformed size of the polylines.