Clock Template for Silverlight

Posted on 10/25/2008 @ 11:09 AM in #Silverlight and WPF by | Feedback | 2815 views

First of all, I've renamed my "WPF" category on my blog to "Silverlight and WPF". I blogged about WPF before Silverlight even existed. If I had known that Silverlight was coming, I wudda named it right to begin with.

Anyway, so, here we go.

Way long ago, when I was still a little kid, I had blogged about creating a ControlTemplate for an Analog clock.

Here is the end result -

You could acheive the above by using code as shown here -

   1:  <Control Template="{StaticResource clockTemplate}"  Width="120" Height="108"  
   2:  DataContext="{Binding Path=Now, Source={StaticResource dateTime}}">

Now, unfortunately since the Silverlight CLR is retarded (restricted), the above won't work.

Why? Well those pretty hour and minute hands are nothing but lines with RotateTransforms applied to them. And the "Angle" property is DataBound to a value that comes out of a ValueConverter. (For more details, please read the details of this blogpost).

Now, my view is that not making "Angle" databindable in Silverlight is an artificial seperation. I don't know why they didn't give me the flexibility of writing elegant code - but - thankfully, a solution exists.

It's in 3 steps

a) Dump the ValueConverter - can't use it here.
b) Remove Databinding on Angle, so the below -->

   1:  <Rectangle x:Name="HourHand" Canvas.Top="21" Canvas.Left="48" Fill="Black" Width="4" Height="30">
   2:     <Rectangle.RenderTransform>
   4:        <RotateTransform x:Name="HourHand2" CenterX="2" CenterY="30" Angle="{Binding Mode=OneWay, Converter={StaticResource hourToAngle}}">
   5:          </RotateTransform>
   6:      </Rectangle.RenderTransform>  
   7:  </Rectangle>

.. will change to ...

<Rectangle x:Name="HourHand" Canvas.Top="21" Canvas.Left="48" Fill="Black" Width="4" Height="30" Loaded="HourHand_Loaded"/>

with the following code-behind

   1:  private void HourHand_Loaded(object sender, RoutedEventArgs e)
   2:  {
   3:      Rectangle HourHand = sender as Rectangle;
   4:      RotateTransform transform = new RotateTransform() ;
   5:      transform.CenterX = 2;
   6:      transform.CenterY = 30;
   7:      DateTime passedValue = Convert.ToDateTime(HourHand.DataContext);
   8:      transform.Angle = (passedValue.Hour * 30) + (12 * passedValue.Minute / 60);
   9:      HourHand.RenderTransform = transform;
  10:  }

.. Yeah that's pretty much it!

Put the whole thing together, and you have a happy silverlight app running in Safari as shown below -->

That's pretty neat huh?

Sound off but keep it civil:

Older comments..

On 7/30/2010 1:30:59 AM ride4sun said ..
Yes you are absolutely right. It took me 3 days to find out that I can not bind to angle. SUPER STUPID GRRRRR

On 7/30/2010 3:25:52 AM Sahil Malik said ..
3 days? OMG, why didn't u ask me earlier!?