Click here to Skip to main content
13,505,299 members
Click here to Skip to main content
Add your own
alternative version


94 bookmarked
Posted 20 Apr 2008

Personal Time Tracker

, 12 Aug 2008
Rate this:
Please Sign up or sign in to vote.
This article describes what I did to write an application to track my billable and non-billable time.


I had a problem, common to a lot of people, of reporting how I am spending my time during the day. I looked at many of the free time tracking programs out there and they didn't really fit my personal needs. So, being a programmer, I wrote a program that met my needs. I am posting it here in the hope that it can meet the needs of others as well.

Personal Time Tracker (PTT) will track time spent on tasks and categorize them by customer. It show time in hours and minutes as well as hours and percentage of an hour. Where I work, we report time in the form of 1.5 for 1 and 1/2 hours.

Another reason (the main reason maybe?) I wrote PTT was also to play around with some .NET features I had not used before. So, there are a lot of .NET tricks and techniques in the code provided.

The main features of this program are:

  • Tracks billable and non-billable time
  • Reporting using the .NET reporting Framework and a custom report dialog
  • Undo support
  • Uses DataGridView with some tweaks
  • Systray application with dynamic menus
  • Automatic saving at a user defined interval

Using the Application

This application does not have a main menu. It is controlled through context sensitive menus and some buttons. When minimized, you right click on the systray icon to access the menu. When the app is visible, you right click on the grid.

The first thing you will need to do is set up your customers and tasks. To set up customers click on the Customer List... button and set up tasks by clicking on the Task List... button. Click on the blank line in each of the dialogs to add a new entry.

Once you have customers and tasks, then you can start tracking your time against them. The easiest way to do that is to right click in the data grid and select a customer from the context menu and then select a task from the customer sub-menu.

You can temporarily stop tracking time against the current activity by checking the Pause check box. When you come back to work on that activity you can uncheck the pause check box and an interruption time will be added from when you paused the activity until when you unpaused it. Or, after pausing an activity you may decide to start a different activity. In that case an interruption is inserted into the paused activity and a new activity is started.

If you modify the start and end time of an activity log entry, then the other log entries will adjust to account for the new time entered. For example, if you change the stop time to be after the start time of the next log entry then the next log entry's start time will be adjusted to be just after to the edited log's end time.

Data Files

The activity logs are stored in XML files with a different file for each month. This way you can archive off old data as desired. If you wish to view the time logs for that month again, you can simply place those files back in the directory with the application again.

About the Code

PTT is a WinForms app written using C# and the .NET 3.0 Framework, therefore it requires some form of Visual Studio 2008 if you want to build the solution.


I had a lot of information to display in the DataGridView on each line and one of these cells needed to hold a description of the activity being performed. So, instead of having a really long cell, I wrote a class to help me manage a multi-line text cell. This class is called DataGridViewMemoCell and is a subclass of DataGridViewTextBoxCell.

It automatically detects if the edit box would go outside the bounding rectangle for the grid control and adjust as required in the PositionEditingPanel method.

The actual cell edit control is called MemoBox and is a subclass of DataGridViewTextBoxEditingControl. The look of the cell edit control is set in the ApplyCellStyleToEditingControl method.

A Note About Shared Sub-Menus

It is important to understand when sharing a sub-menu between more than one parent menu that you can't do it....but you can imitate it. PTT builds its customer and task sub-menu dynamically since this is data driven. This sub-menu is displayed in the main grid context menu and in the systray menu. I didn't want to have to do this for two different menus so I decided to simply share the customer sub-menu between the two menus. My first attempt was to create a place holder in one menu and then grab a reference to that menu on start up and add it to the other menu. That sort of worked. The problem was that when you add a menu to another menu, it removes itself from its previous parent. That means a menu can only be owned by one other menu. That made sense once I thought about it. That was not a show stopper since only one menu would ever be visible at a time. So, instead of sharing the sub-menu, I intercepted the Opening event of the menu and added the customer sub-menu at that time if it was not already in the menu.

Having Esc Minimize the Application

I wanted to very easily hide PTT in the systray. I decided that pressing the ESC key would be a good way to accomplish this. I have seen this in other applications so it is kind of a standard. This was a bit tricky though since I didn't have a main menu. I ended up making a button that on startup I had to move behind the grid to hide it. I then attached a shortcut key of ESC to that button. On the click handler for the button, I simply minimized the form. I tried making the button hidden but then the shortcut didn't work.


I wanted to have reports that showed a summary of activity. I decided that using the .NET printing hooks would be the easiest way to accomplish this. So I wrote a dialog to host a PrintPreviewControl. I then wrote a custom subclass of PrintDocument called ReportPrintDocument which allowed me to set the type of report to generate and the options for the report. Someday I will make subclasses of the print document for each report type but I didn't get around to that yet.


I needed a stack to hold the undo information but I wanted to limit the number of elements that could be in that stack. So I wrote the LimitedStack<T> class to handle that for me. I probably could have sub-classed Stack<T> but there was so little that I needed from it that it wasn't really worth it and I didn't need most of what it offered for my purposes.

Detecting StandBy Mode

I had a problem of forgetting to click the Done with Task button before putting my laptop into StandBy mode when leaving for the day. So, I added code to detect when the computer is entering stand by mode and to clear the current task and save. This is accomplished by using the Microsoft.Win32.SystemEvents.PowerModeChanged event. This behavior is optional and is controlled through a new check box. Here is the event handler for that event:

private void OnPowerModeChanged(object sender,
    Microsoft.Win32.PowerModeChangedEventArgs e)
    if (_clearOnStandyCheckBox.Checked
        && e.Mode == Microsoft.Win32.PowerModes.Suspend
        && null != m_currentActivity)
        // Update Time
        m_currentActivity.StopTime = DateTime.Now;
        // Going into standby mode so clear current event
        m_currentActivity = null;
        // Save latest changes
        m_isDirty = !LogFileManager.SaveDataFile();


17th April, 2008: - First posted version

11th August 2008:

  • Added Standby detection
  • Fixed some problems of manually editing times
  • Fixed a bug of trying to add log entries when no customers or tasks are set up


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Vance Kessler
Web Developer
United States United States
I have been developing .NET applications since 2001 and have been working in software development since 1989.

You may also be interested in...

Comments and Discussions

GeneralMy vote of 4 Pin
seanxywu@gmail.com30-Jul-14 6:51
memberseanxywu@gmail.com30-Jul-14 6:51 
GeneralExcellent Program!! Pin
M Schneider18-Jul-13 9:51
memberM Schneider18-Jul-13 9:51 
GeneralUseful... Pin
Al Rice17-May-11 5:11
memberAl Rice17-May-11 5:11 
GeneralSave in Local App Data folder [modified] Pin
PankajMishra27-Jan-11 19:40
memberPankajMishra27-Jan-11 19:40 
GeneralRe: Save in Local App Data folder [modified] Pin
alexpj.129-Dec-16 13:31
memberalexpj.129-Dec-16 13:31 
GeneralUnhandled exception on Windows 7 with VS2010 Express / .NET 4.0 Pin
bittoom15-Dec-10 2:02
memberbittoom15-Dec-10 2:02 
GeneralRe: Unhandled exception on Windows 7 with VS2010 Express / .NET 4.0 Pin
Vance Kessler15-Dec-10 3:50
memberVance Kessler15-Dec-10 3:50 
QuestionWhat exactly is Billable Time Pin
Dreshar3-Aug-10 1:02
memberDreshar3-Aug-10 1:02 
AnswerRe: What exactly is Billable Time Pin
Vance Kessler3-Aug-10 3:34
memberVance Kessler3-Aug-10 3:34 
GeneralNew generation time tracking tool ( Premember ) Pin
1dead18-Jul-09 3:42
member1dead18-Jul-09 3:42 
GeneralRe: New generation time tracking tool ( Premember ) Pin
Vance Kessler8-Jul-09 4:08
memberVance Kessler8-Jul-09 4:08 
GeneralRe: New generation time tracking tool ( Premember ) Pin
1dead18-Jul-09 4:16
member1dead18-Jul-09 4:16 
QuestionWhere is the data saved? Pin
subaqua4-Jun-09 10:33
membersubaqua4-Jun-09 10:33 
AnswerRe: Where is the data saved? Pin
Vance Kessler4-Jun-09 11:47
memberVance Kessler4-Jun-09 11:47 
GeneralRe: Where is the data saved? Pin
subaqua5-Jun-09 5:33
membersubaqua5-Jun-09 5:33 
GeneralRe: Where is the data saved? Pin
Vance Kessler5-Jun-09 5:46
memberVance Kessler5-Jun-09 5:46 
GeneralRe: Where is the data saved? Pin
Denver Dave3-Dec-09 10:02
memberDenver Dave3-Dec-09 10:02 
GeneralRe: Where is the data saved? Pin
Vance Kessler4-Dec-09 4:12
memberVance Kessler4-Dec-09 4:12 
GeneralRe: Where is the data saved? Pin
Wrangly30-Jul-13 21:55
memberWrangly30-Jul-13 21:55 
GeneralRe: Where is the data saved? Pin
Vance Kessler31-Jul-13 3:03
memberVance Kessler31-Jul-13 3:03 
GeneralRe: Where is the data saved? Pin
Wrangly31-Jul-13 3:07
memberWrangly31-Jul-13 3:07 
GeneralRe: Where is the data saved? Pin
Member 1042278224-Nov-13 5:56
memberMember 1042278224-Nov-13 5:56 
AnswerRe: Where is the data saved? Pin
alexpj.130-Dec-16 11:46
memberalexpj.130-Dec-16 11:46 
GeneralReporting Pin
PeterA27-May-09 14:56
memberPeterA27-May-09 14:56 
GeneralRe: Reporting Pin
Vance Kessler28-May-09 1:28
memberVance Kessler28-May-09 1:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.180417.1 | Last Updated 12 Aug 2008
Article Copyright 2008 by Vance Kessler
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid