In this article I am going to create an Analog Clock with a sweeping second hand and rotate the minute and hour hands using Visual C# code, using Microsoft Expression Blend; the project type is Windows Presentation Foundation (WPF). The final work should look something like the following image:
1. We start off by designing our clock.
Open a New Project and select WPF Application, then change it's name to AnalogClock.
2. Change the background of your layout using gradient brush from the properties window according to your choice so that your screen will be like this:
3. In the Brushes section ensure that the Background is selected then click on the No brush tab and
Select the Ellipse tool from the tool box. Draw out a circle in Window1 while holding the shift key to constrain the shape of the circle.
4. While the circle is still selected change its Fill to a Gradient brush. Change the gradient to a Radial gradient and adjust its properties to look like the following image. Click on Stroke and then on the No Brush tab to remove the stroke.
5. Rename the circle as Circle1 in the Objects and Timeline panel. Now select the Brush Transform tool from the tool box to adjust the gradient to look like as follows:-
6. Copy-paste a new circle by right clicking on Circle1 in Objects and Timeline. Now, rename it to Circle2 and make it slightly smaller than Circle1. Hold ALT+SHIFT to constrain the shape of the circle while maintaining the center point and change its color to a little darker than the first one
7. With Circle2 still selected copy-paste another circle and again rename the new circle as Circle3 and resize it to make it slightly smaller than Circle2 change the Fill of Circle3 to white so that the image looks like as follows:
8. Next we draw the Minute Hand, Hour Hand, and Second Hand with the help of a Rectangle and then color them for looks. After drawing of a Minute Hand use Copy-Paste for the other two Hands and resize them by adjusting the height and width. Rename these rectangles as Minutehand, Hourhand and Secondhand accordingly.
9. Change their center points by clicking on the bottom center point in the Translate tab of the Transform section.
10. We will now get our Rectangle's (Hour, Minute, Second) center point to align with that of our circles. Select Circle3 and copy-paste a new circle, resize it as a Centre point of our clock by holding ALT+SHIFT then change its Fill to a color of your own choice and also rename it to CentrePoint.
11. Now with the help of label we will show the numbering on a clock and for that Select a label from the toolbox and rename it to "Label12", change its content from the common properties menu as "12" and set its fill as white, BorderBrush as No Brush and place it on top as shown in the
Image:
12. Use Copy-Paste Option to Draw all Numbers (1,2,3,4,5,6,7,8,9,10,11) and place them by changing their margins. After this our design will change like this:
Note: You can change the effects and design according to your choice.
13. In this step we use a textbox to show the current date. Select a text box from the tool Window and draw it to the bottom of the CentrePoint and make it Blank from the Common Properties -> Text -> " "(Blank) and properties should be like this:
14. In order to make our clock work we shall write some code that will rotate triangles Hourhand, Minutehand and Secondhand by certain angles at specific intervals. To achieve this we shall create two RotateTransform objects and set their Angle properties to various values at a set interval.
Expand Window1.xaml and double click on Window1.xaml.cs to open the code behind file in Blend's code editor. If you are using Expression Blend 2 then in the Project panel right click Solution and select 'Edit In Visual Studio' from the context menu.
CODING :
// Create an instance of RotateTransform objects
private RotateTransform MinHandTr = new RotateTransform();
private RotateTransform HourHandTr = new RotateTransform();
private RotateTransform SecHandTr = new RotateTransform();
// Create an instance of DispatcherTimer
private DispatcherTimer dT = new DispatcherTimer();
// to set the Angles for the Minutehand, Hourhand, Secondhand
public void dispatcher_Tick(object source, EventArgs e)
{
MinHandTr.Angle = (DateTime.Now.Minute *6);
HourHandTr.Angle = (DateTime.Now.Hour * 30) + (DateTime.Now.Minute*0.5);
Minutehand.RenderTransform = MinHandTr;
Hourhand.RenderTransform = HourHandTr;
}
// to set the Date in the textbox
textBox1.Text = DateTime.Now.ToShortDateString();
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace Analog_clock
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow
{
//Create an instance of RotateTransform objects
private RotateTransform MinHandTr = new RotateTransform();
private RotateTransform HourHandTr = new RotateTransform();
private RotateTransform SecHandTr = new RotateTransform();
//Create an instance of DispatcherTimer
private DispatcherTimer dT = new DispatcherTimer();
public MainWindow()
: base()
{
Loaded += Window1_Loaded;
this.InitializeComponent();
// Insert code required on object creation
// below this point.
}
public void dispatcher_Tick(object source, EventArgs e)
{
MinHandTr.Angle = (DateTime.Now.Minute *6);
HourHandTr.Angle = (DateTime.Now.Hour * 30) + (DateTime.Now.Minute * 0.5);
textBox1.Text = DateTime.Now.ToShortDateString();
Minutehand.RenderTransform = MinHandTr;
Hourhand.RenderTransform = HourHandTr;
}
private void Window1_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
dT.Tick += dispatcher_Tick;
//Set the interval of the Tick event to 1 sec
dT.Interval = new TimeSpan(0, 0, 1);
//Start the DispatcherTimer
dT.Start();
secondHandTransform.Angle = (DateTime.Now.Second * 6);
}
}
}
15. To create a sweeping second hand we should use the storyboard so that we can animate secondhand to sweep.
16. Click on the trigger Window and Add event to it as shown:
17. On window load Event Add new Action a pop-up appeared that "No Story board exists for you to begin or to control. One will be created" click ok.
18. The code for Second Hand Animation is as under:
19. Now its time to run your application you will get a good looking clock running on your system screen
MainWindow.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
x:Class="Analog_clock.MainWindow"
x:Name="Window" Title="MainWindow" SizeToContent="WidthAndHeight" AllowsTransparency="True" WindowStyle="None" Loaded="Window1_Loaded">
<Window.Resources>
<Storyboard x:Key="OnLoaded1">
<DoubleAnimation x:Name="secondAnimation" Storyboard.TargetName="secondHandTransform" Storyboard.TargetProperty="Angle"
Duration="0:1:0" RepeatBehavior="Forever" By="360" />
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard x:Name="OnLoaded1_BeginStoryboard" Storyboard="{StaticResource OnLoaded1}"/>
</EventTrigger>
</Window.Triggers>
<Grid x:Name="LayoutRoot">
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFF9F3EF" Offset="0.29"/>
<GradientStop Color="#FFDC6918" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<Ellipse x:Name="Circle1" Margin="60">
<Ellipse.Fill>
<RadialGradientBrush GradientOrigin="0.5,0.159">
<GradientStop Color="#FFF9F9FD" Offset="0"/>
<GradientStop Color="#FF4E429D" Offset="1"/>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse x:Name="Circle2" Margin="79">
<Ellipse.Fill>
<RadialGradientBrush GradientOrigin="0.475,0.506">
<GradientStop Color="#FFF9F9FD" Offset="0"/>
<GradientStop Color="#FF423791" Offset="1"/>
<GradientStop Color="#FF594FB2"/>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse x:Name="Circle3" Margin="88">
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<GradientStop Color="#FFF9F9FD" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
<GradientStop Color="White"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Label x:Name="Label12" Content="12" Margin="178,79,181,0" FontWeight="Bold" FontStyle="Italic" FontSize="21.333" Background="{x:Null}" Height="39" VerticalAlignment="Top" d:IsLocked="True">
<Label.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFF31313" Offset="1"/>
</LinearGradientBrush>
</Label.Foreground>
</Label>
<Label x:Name="Label9" Content="9" Margin="88,185,0,177" FontWeight="Bold" FontStyle="Italic" FontSize="21.333" Background="{x:Null}" HorizontalAlignment="Left" Width="38" Height="38">
<Label.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFF31313" Offset="1"/>
</LinearGradientBrush>
</Label.Foreground>
</Label>
<Label x:Name="Label3" Content="3" Margin="0,185,88,177" FontWeight="Bold" FontStyle="Italic" FontSize="21.333" Background="{x:Null}" HorizontalAlignment="Right" Width="26" Height="38">
<Label.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFF31313" Offset="1"/>
</LinearGradientBrush>
</Label.Foreground>
</Label>
<Label x:Name="Label6" Content="6" Margin="187,0,187,80" FontWeight="Bold" FontStyle="Italic" FontSize="21.333" Background="{x:Null}" Height="38" VerticalAlignment="Bottom">
<Label.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFF31313" Offset="1"/>
</LinearGradientBrush>
</Label.Foreground>
</Label>
<Label x:Name="Label1" Content="1" Margin="0,100,138,0" FontWeight="Bold" FontStyle="Italic" FontSize="16" Background="{x:Null}" Height="30" VerticalAlignment="Top" HorizontalAlignment="Right" Width="21">
<Label.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFF31313" Offset="1"/>
</LinearGradientBrush>
</Label.Foreground>
</Label>
<Label x:Name="Label2" Content="2" Margin="0,136,103,0" FontWeight="Bold" FontStyle="Italic" FontSize="16" Background="{x:Null}" Height="30" VerticalAlignment="Top" HorizontalAlignment="Right" Width="21">
<Label.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFF31313" Offset="1"/>
</LinearGradientBrush>
</Label.Foreground>
</Label>
<Label x:Name="Label4" Content="4" Margin="0,0,100,135" FontWeight="Bold" FontStyle="Italic" FontSize="16" Background="{x:Null}" Height="30" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="22">
<Label.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFF31313" Offset="1"/>
</LinearGradientBrush>
</Label.Foreground>
</Label>
<Label x:Name="Label5" Content="5" Margin="0,0,135,98" FontWeight="Bold" FontStyle="Italic" FontSize="16" Background="{x:Null}" Height="30" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="21">
<Label.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFF31313" Offset="1"/>
</LinearGradientBrush>
</Label.Foreground>
</Label>
<Label x:Name="Label7" Content="7" Margin="135,0,0,98" FontWeight="Bold" FontStyle="Italic" FontSize="16" Background="{x:Null}" Height="30" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="23">
<Label.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFF31313" Offset="1"/>
</LinearGradientBrush>
</Label.Foreground>
</Label>
<Label x:Name="Label8" Content="8" Margin="100,0,0,135" FontWeight="Bold" FontStyle="Italic" FontSize="16" Background="{x:Null}" Height="30" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="30">
<Label.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFF31313" Offset="1"/>
</LinearGradientBrush>
</Label.Foreground>
</Label>
<Label x:Name="Label10" Content="10" Margin="94,136,0,0" FontWeight="Bold" FontStyle="Italic" FontSize="16" Background="{x:Null}" Height="30" VerticalAlignment="Top" HorizontalAlignment="Left" Width="32">
<Label.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFF31313" Offset="1"/>
</LinearGradientBrush>
</Label.Foreground>
</Label>
<Label x:Name="Label11" Content="11" Margin="125,100,0,0" FontWeight="Bold" FontStyle="Italic" FontSize="16" Background="{x:Null}" Height="30" VerticalAlignment="Top" HorizontalAlignment="Left" Width="33">
<Label.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFF31313" Offset="1"/>
</LinearGradientBrush>
</Label.Foreground>
</Label>
<TextBox Height="18" Name="textBox1" Margin="168,0,166,167" TextWrapping="Wrap" VerticalAlignment="Bottom" BorderBrush="{x:Null}" FontSize="9.333" FontWeight="Bold" SelectionBrush="{x:Null}" Background="White">
<TextBox.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black"/>
<GradientStop Color="#FFD22F2F" Offset="1"/>
</LinearGradientBrush>
</TextBox.Foreground>
</TextBox>
<TextBox Height="18" x:Name="textBox2" Margin="158,0,157,155" TextWrapping="Wrap" VerticalAlignment="Bottom" BorderBrush="{x:Null}" FontSize="9.333" FontWeight="Bold" SelectionBrush="{x:Null}" Background="White" FontStyle="Italic" Text="Made by Nipun">
<TextBox.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF1CCA1E" Offset="1"/>
<GradientStop Color="#FF2100FF"/>
</LinearGradientBrush>
</TextBox.Foreground>
</TextBox>
<Rectangle x:Name="Minutehand" Height="75" Margin="195,122,197,0" VerticalAlignment="Top" Width="8" RenderTransformOrigin="0.5,1">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<GradientStop Color="#FFE42C5F" Offset="1"/>
<GradientStop Color="#FFE42C5F"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle x:Name="Hourhand" Height="45" Margin="195,152,197,0" VerticalAlignment="Top" RenderTransformOrigin="0.5,1">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<GradientStop Color="#FF1F0091" Offset="1"/>
<GradientStop Color="#FF1F0091"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle x:Name="Secondhand" Height="100" Margin="198,97,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="2" d:LayoutOverrides="VerticalAlignment" RenderTransformOrigin="0.5,1">
<Rectangle.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="secondHandTransform"/>
</TransformGroup>
</Rectangle.RenderTransform>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<GradientStop Color="#FF100F0F" Offset="0.996"/>
<GradientStop Color="Black"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Ellipse x:Name="CentrePoint" Margin="185">
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<GradientStop Color="#FFF9F9FD" Offset="0"/>
<GradientStop Color="#FF21076C" Offset="1"/>
<GradientStop Color="#FF4800B6"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse x:Name="CentrePoint_Copy" Margin="197" RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="-1"/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Ellipse.RenderTransform>
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<GradientStop Color="#FFF9F9FD" Offset="0"/>
<GradientStop Color="#FFB60043" Offset="1"/>
<GradientStop Color="#FFB60043"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
</Window>