Introduction
This article demonstrates how an irregular, skinnable world clock can be created and how application settings can be persisted using XML. The clock has been quite handy for working out who's awake and at their desk on a development project that spans multiple time zones.
Background
This Three Zone World Clock was inspired by the article by Iulian Serban called How to build a Clock control. I have used a stripped down version of Iulian Serban's clock painting code and added logic for dealing with three clocks, handling transparency and the loading and saving of settings.
Using the code
I found when I started experimenting with transparent bitmaps on forms that there are a myriad ways of stuffing up transparency. After many searches and experiments I wrote this routine which seems to handle the transparency correctly. The routine loads a named skin file up from the application directory and then sets this as the background image for the form. Amazingly without the g.Clear
statements subsequent bitmaps would be layered one on top of another - this was certainly a suprise feature for me!
private void SetSkin(string skinName, bool initializing)
{
if(File.Exists(skinPath))
{
Bitmap skinBmp = (Bitmap)Bitmap.FromFile(skinPath);
if(!initializing)
{
Graphics g = this.CreateGraphics();
g.Clear(Color.Black);
g.Clear(TransparencyKey);
}
skinBmp.MakeTransparent(skinBmp.GetPixel(1,1));
BackgroundImage = skinBmp;
TransparencyKey = skinBmp.GetPixel(1,1);
Invalidate();
}
}
Persisting the Application State to XML
An XML file seemed to be the obvious choice for storing the application settings. The XML serializer was used to persist an AppSettings
object containing three ClockSettings
objects. Once the settings object model has been created, the code to save and load settings is pleasingly minimal. One pitfall I came across when using the XML serializer is that you must include default constructors for the classes being persisted, even if these default constructors serve no apparent purpose they have to be there or you get a lovely System.InvalidOperationException
private void SaveSettings()
{
string appPath = Path.GetDirectoryName(Application.ExecutablePath);
m_appSettings.Save(appPath + "\\settings.xml");
m_saved = true;
}
Future Enhancements
Dave has been busy suggesting enhancements I could make, but heck I want my lunchtimes back so here is a list of "nice to have" things that I probably will not get time to code...
- More clocks - would be nice if there were a configurable number of clocks (adding clocks is relatively easy but its making them look nice that's the tricky bit). At the moment the code is hardwired to three clocks, but I think I've left the door half open to add more.
- An editor for setting up clock names and times - I agree that hacking the XML is not very nice!
- Deployment from the top of the screen - not sure what Dave's getting at here but it has something to do with the clocks sliding down like a roller blind from the top of the screen. Hmmm.
- AM/PM indicator. Like all true analog clocks, my clocks currently give absolutely no clue as to whether its day or night.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.