Introduction

Here, an analog clock has been created with a VB.NET control library. It is a clock control which has almost all the functionality that this type of control can have, and it is fully customizable. Since this is a control library, you can use it in C++, C#, J#, and VB.NET projects in the .NET environment.

I created this control to help someone in VB Forums. At the beginning, it was a very simple clock, but then it became somewhat advanced after I added many properties, events, and a functionality that makes the clock very flexible.

Adding the Component

To use the control, you just need to add it into the VS.NET Toolbox. Right click in the Toolbox area, and select the "Choose Items" menu item. It will then open the "Choose Toolbox Item" window. You go to the directory that contains the "AnalogClockLib.dll" file and select it, then click the OK button. This will add the control onto the Toolbox.

Finally, you drag and drop the control onto your forms. Also, in order to see the descriptions of the properties or methods in the Code Designer, you should copy the "AnalogClockLib.xml" file into your project's folder.

Background

The clock control is a Windows UserControl. Almost all the elements of the clock have been constructed (the core of the element) with the GraphicsPath data type. They contain a member variable Base-Path which is a GraphicsPath of the element. These Base-Paths are used differently for each element. For example, the marker's Base-Path represents a GraphicsPath constructed at 12 hour position and than rotated using a Matrix object. Since it is rotated only once, there is no need fore any other helper objects. The clock's hands have two member variables of type GraphicsPath: Base-Path and Shift-Path. The Base-Path of the hands are always positioned at 12 o' clock, and only reshaped if the element's shape (width, length, or style) is modified. On the other hand, the Shift-Path is the actual GrapicsPath of the hand at any given time. Shift-Path is the copy of the rotated Base-Path.

Using the Code

Although you can do almost anything with this control, I will show you only how to paint the hour-hand of the clock with a PathGradientBrush. Note, in this fashion, you can paint the elements with any brush.

It is very nice to see the clock hand's gradient, so here is how you can do that. Basically, you set the Brush property of the hands to a newly created gradient brush object in the hands' paint event.

Sometimes people ask me why the clock is one hour off after daylight savings or how we can be sure that clock shows the correct time always. Well, if this is the case with you, then you need to make sure that the clock's UtcOffset is always accurate. This is how you can do it:

PrivateSub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) HandlesMyBase.Load
'Set UTC offset to the system utc offset when the application loads
Me.Clock1.UtcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now)
EndSubPrivateSub Clock1_TimeChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Clock1.TimeChanged
'Set UTC offset to the system utc offset every time clock time changes.
'If the property has the same value it will do nothing.
Me.Clock1.UtcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now)
EndSub

Analog Clock Control Information

History

1.0.2813.38699 -- Some minor changes to the number and marker styles. Also. the UTC offset values range is changed that accepts values from -23:00:00 to 23:00:00.

1.0.2847.27310 -- This update adds a property that can be used to get/set the clock's frame line color. Also, there are some corrections to the clock. The update is recommended.

1.0.2917.23783 -- A small bug fix

1.0.3002.36694 -- Added minute marker width property

1.0.3223.6598 -- This update includes major changes to the implementation of the clock. If you liked the previous versions of the analog clock, then you will love this one. In this version, you can modify every element of the clock at design and run time. There is a lot of good stuff I would like to mention, but it is better you try it yourself. I will remind you to check all the properties of the clock, in particular, the Element category in the Properties window which contains the clock's hands, markers, etc. I hope you will like it.

I am an automation engineer and a total beginner with VB. I have been looking to display the machine position in degrees on my screen and I think this would be perfect. I would need to have one off the hands follow an input that I have from 0 to 359 etc...
is there a way i could do this?

Hi Arman,
thank you for your excellent program. I am using it for educational purposes, to teach mentally handicapped children to read the clock. I am writing in VB under Visual Studio 2010 of whose intricacies, I have to admit, I know and understand but little.
Luckily I had the design of the Windows form mostly finished before I added your control as from the moment I did so even the slightest change inside the forms editor, eg of the text value of a label, has been taking an increasingly long time before I can continue, especially when I change to code view, 'long' meaning at least one, by now up to three minutes. That makes anything like fluent work impossible. I started a couple of new projects, some on my desktop computer (Athlon X2 5000+, Win7 (x64), 4 GB memory, >100 GB free HD space), others on my laptop, which behaved faultlessly, but as soon as I added your control the same crippling lack of performance set in.
I have learned from my research in Google that third party components often cause problems, which is why I suspect - no, hope! - that you could have an idea of what I might have done wrong (cf my limited understanding of VS) or could do to improve my dilemma.

I did test the control in VS 2010 and encounter the same problem. I have to examine this problem. I can't say what causes the problem but one thing is sure, the control was working with framework 3.5. In fact the control is written with VS 2008 so it uses framework 3.5. Most likely the framework is the problem since some stuff has been changed in framework 4.0. I have to do tests first, meanwhile check my website for updates. Thanks for reporting it.

Warning 1 The referenced assembly "AnalogClockControl" could not be resolved because it has a dependency on "System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" which is not in the currently targeted framework ".NETFramework,Version=v4.0,Profile=Client". Please remove references to assemblies not in the targeted framework or consider retargeting your project. IITS 2f

I simply add the Control to a new Form. When I'm build the project I got the error message "Code generation for property 'Symbols' failed. Error was: "SymbolConverter" is unable to convert "AnalogClock.Symbol" to "System.ComponentModel.Design.Serialization.InstanceDescriptor". When I close and reopen my project the proberties for the smallmarkers and symbols were not saved and has the default values. Do I anything wrong?

Ok, Thank you, I tried Version 1.5.0.2. With 1.5.0.3 the error is gone. But, isn't the source code available anymore? Because I want to show the state of an external clock and not the current time on my pc. Therefore I need the "value" proberty writeable which is set readonly by the developer, I haved changed this for me in the pervious(source code available) version, but without sourcecode......

When you say current time what do you mean? Do you mean the current time of your system, the current time for any time zone or for all? Do you want to show only the clock graphics whose hands not moving? Explain a little bit more of what you want.

Hi, unfortunately the clock design doesn’t let you directly change the time value because the control has inner timer that updates the clock control. As I said, the clock time only depends from UtcOffset property and can be controlled only from this property. What I can suggest you for setting a start custom time for the clock is to do a little calculation and set the UtcOffset property accordingly. Here I wrote a little example of how to do that.
Hope this will help you.

Ok, this workaround is possible for me. I set Clock1.Running = False either on Form_load or in clock1 properties. And set the time via my function
Private Sub fSetNewClockTime(ByVal oNewDate As DateTime)
Dim utcDt As DateTime = DateTime.UtcNow 'The current UTC dateTime. This is needed beacuse the clock internal works with UTC dateTime.
Clock1.UtcOffset = New TimeSpan(0, oNewDate.Hour - utcDt.Hour, oNewDate.Minute - utcDt.Minute, oNewDate.Second - utcDt.Second)
End Sub

Is anybody else running into a Daylight Savings Time problem with this control?

I set my UTC to -7:00:00 (I live in USA Mountain Time Zone). It's fine in the winter, but in the summer it's an hour off.

My computer is set to "automatically adjust for daylight savings time"

My computer displays the correct time, but this control is off by an hour.

Is there a way to disable the UTC offset and just have it display the computer's time? Seems like this would be more useful than having so much time adjustment logic built into the control. I guess there are instances where this would come in handy. But I would think 99% of the time, the user would just want to display the computer's time (not some other time zone in the world)

There is no time adjustment logic built into the control. The control has UtcOffset property and it is the developer’s responsibility to change it when the time adjustment takes place. To show the correct system time always you need to set the UtcOffset property when the clock app starts. If your system is always on than you can put a line in the TimeChanged event handler where you set UtcOffset to the system utc offset. Now you can always be sure that it shows the correct system time.

Thank you for the answer. I will try working around this problem using your suggestion.

So the system UTC offset will CHANGE when Daylight savings time kicks in? e.g. if I am GMT-7:00 normally, will the system UTC offset return GMT-6:00 in the summer???? I've never looked that this so I'm not sure. I'll experiment.

Also - I'd like to point out that when you said:
"There is no time adjustment logic built into the control"

That does not appear to be 100% correct. Obviously - it is adjusting time based on the UTC offset. Basically, it appears that the control is location aware, but not DST aware.

What I was suggesting is to have a setting to make the control truely behave like you stated - *NO* time adjustment. Just display the system time without regard to adjusting for UTC offsets, Daylight Savings, whatever. I think the majority of people using the control will be using it to display the system time. And that time is already adjusted for location and DST by Windows for us.

Not only will this be one less thing to set up when adding the control and less "code behind" to implement (to update the UTC offset everytime the application starts up - or every update).

The only advantage I see to having a UTC offset built into the control, is to allow you to display times for time zones other than your own. Certainly, some applications would call for this, but this would be the exception I would think. I would expect the default behavior for this control to be "display the system time"

I do believe that system UTC offset changes when the daylight savings time takes place. If your system shows the correct time than the clock control will show it the same if you put that extra line in the time changed event handler as we have discussed.
-
As for your suggestion, well some times you want to show not only the system time but other timezone’s time. There for the control needs this property to make it possible. I think adding one line of code to the rest is nothing compare to what we gain.
-
Anyway, I have put some code examples in here. You can check them out if you need.

You can reference the clock control (dll file) in C# project as in VB.Net. As to answer to your question, yes it is possible since C#, VB.Net are .Net languages. But again you don’t need it since you can add the control to any .Net windows project.

Something odd - when this control is placed on a form it seems to trap the cursor keys and I can't see why. I'm using the cursor keys to move other objects around. NumPad and other normal keys are not affected but in on the form KeyDown event for example e.Keyode=Keys.Down is no longer occurring, it seems to be being consumed by the clock control (key preview is true on the form)

I would like to be able to set the clock to a specific time, and not have it update as time passes. I'm looking for a control in which a user can set a time for an event using an interface similar to this.

Hi Neo, I am currently working on the component changing some properties. I will post the updated version in here as soon as I finish it. For your problem, I can say that the updated component's UpdateClock property will determine if the clock should be updated or not. As for setting an exact time for the Analog Clock is possible only through the UtcOffset property. This is the only property that changes the clock’s time and hands.

Hi Neo, I updated the Analog Clock control as I promised. This version is superior to the previous ones. For your problem, you can set the clocks UpdateClock property to False and set the time through the UtcOffset property. I hope this helps.

Unfortunately the control doesn’t have that functionality by default. The only way to change the clock time is by setting its UTC offset. It is designed that way for consistency with the used UTC offset. This means that when you drag the hand it will no more work with UTC offset. One way I can think of doing this is to set the UTC offset accordingly to the mouse drop location. Of course you need to calculate that location to the UTC offset and set it accordingly, but this is not an easy work.