One of the key ideas at the heart of the custom control architecture in formsPlayer is the separation of the data from how it is rendered. XForms lends itself very well to this, since it was defined from the ground up with a Model-View-Controller (MVC) 'approach'. This means that data such as the locations we were dealing with in the simple map control tutorial, can be manipulated in other controls, or even used as the basis for other calculations, without affecting the rendering of the data.
This approach also means that we have a standard way that changes to the data are communicated to and from the controls, saving us the need to keep inventing new event names each time we create a new widget.
Although these points may seem obvious, we often see custom controls that have all of the functionality in the user interface. When this happens we obviously don't have an MVC architecture, since without some data there is nothing to put in a 'view'. That might sound like pedantry but by packing the control full of functionality and dropping the MVC approach, we dramatically reduce the usefulness of our control.
A good example is a clock control. Whether they use SVG, XAML, Java or C#, writers of clock widgets always put the timing element in the control itself. Take the Silverlight clock example; the code involves creating a nice looking analogue clock using XAML, but if we look at the code that actually keeps track of the time, we see this:
<Canvas Opacity="0" x:Name="parentCanvas" Loaded="setClockTime">
<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded"
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation x:Name="hourAnimation" Storyboard.TargetName="hourHandTransform" Storyboard.TargetProperty="Angle" From="180" To="540" Duration="12:0:0" RepeatBehavior="Forever"/>
<DoubleAnimation x:Name="minuteAnimation" Storyboard.TargetName="minuteHandTransform" Storyboard.TargetProperty="Angle" From="180" To="540" Duration="1:0:0" RepeatBehavior="Forever"/>
<DoubleAnimation x:Name="secondAnimation" Storyboard.TargetName="secondHandTransform" Storyboard.TargetProperty="Angle" From="180" To="540" Duration="0:1:0" RepeatBehavior="Forever"/>
<DoubleAnimation Storyboard.TargetName="parentCanvas" Storyboard.TargetProperty="Opacity" From="0" To="0.7" Duration="0:0:4"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Canvas.Triggers>
...
</Canvas>
This mark-up creates a clock-face and hands for the hours, minutes and seconds (removed from this snippet to make it easier to read), and then animations are created which rotate the hands from 180 degrees to 540 degrees (i.e., a full 360 degree rotation), taking the correct amount of time for each hand--12 hours for the hour hand, 60 minutes for the minute hand, and one minute for the second hand. Although this looks roughly OK as a clock--in a separate document the control is at least initialised with the current time--we have no way of ensuring its accuracy, since once it has been initialised we are dealing only with animations and not the current time. But more important even than the accuracy, since the clock will only ever show the current time, it means that we can't use the same widget in other situations, such as:
- to show multiple clocks, each in a different time-zone;
- to show the time that a flight or train will depart and arrive;
- to show the amount of time remaining in a presentation;
- to show the time that a photograph was taken;
- and so on.
However, if we can create a version of this Silverlight clock that does not move the hands itself but instead does nothing more than place the hands at the correct position based on whatever data it is given, then we would be able to re-use the widget in all of the places just mentioned. And in addition, we'd also be able to swap the widget out for a completely different widget in the future, if the need ever arose.
In the next section we'll illustrate these points by showing how we can create a custom clock control, using XAML and Microsoft's Silverlight.

