Introduction
In this article we are going to see how to use the System.Windows.Forms.Timer and File IO, in the System.IO namespace, to create an application to track time. The goals of this application are: 1. Allow users to accurately track the amount of time spent of different tasks. 2. Be simple to use and deploy.
Using the code
We are going to want a clock to display the amount on time spent on a task. For this we are going to want a timer. A timer object will raise an event at specified intervals. We can use this to make the clock up to update itself every second. We put the following code in the form's load method to set this up:
Set Up the Timer
tmrDigitalClock = new System.Windows.Forms.Timer();
tmrDigitalClock.Enabled = true;
tmrDigitalClock.Interval = 1000;
tmrDigitalClock.Tick += new System.EventHandler(tmrDigitalClock_Tick);
private void tmrDigitalClock_Tick(object sender, System.EventArgs e)
{
if (starttime != System.DateTime.MinValue)
{
stoptime = DateTime.Now;
System.TimeSpan duration = stoptime.Subtract(starttime);
lblTime.Text = ReadableDuration(duration);
}
}
We use this method to tell the clock to change the label indication the time currently spent on the task at hand. The variables starttime and stoptime are System.DataTime variables. When the user hits the start button, the starttime variable is set to System.DateTime.Now, otherwise it is set to System.DateTime.MinValue. We calculate the duration by subtracting the current time from the time the task was started and update the label accordingly.
Setup UI events to start and stop the timer.
Next we add two buttons to Start and Stop time tracking. For the Start button we add the following method to handle the click event:
private void Start_Click(object sender, EventArgs e)
{
if (cboTimeCode.SelectedIndex < 0)
{
MessageBox.Show("Must select a code.");
return;
}
cboTimeCode.Enabled = false;
txtTicket.Enabled = false;
Start.Enabled = false;
Stop.Enabled = true;
starttime = DateTime.Now;
}
For the Stop button we add the following method to handle the click event. This method calculates the amount of time spent on the task and saves it to the file.
private void Stop_Click(object sender, EventArgs e)
{
stoptime = DateTime.Now;
System.TimeSpan duration = stoptime.Subtract(starttime);
starttime = System.DateTime.MinValue;
today = DateTime.Now;
TextWriter tw = File.AppendText(datafile);
tw.WriteLine(today.ToString("M/d/yyyy") + delimiter + cboTimeCode.SelectedItem + delimiter +
txtTicket.Text + delimiter + DurationMinutes(duration));
tw.Close();
cboTimeCode.Enabled = true;
txtTicket.Enabled = true;
cboTimeCode.SelectedIndex = -1;
txtTicket.Text = null;
lblTime.Text = "00:00:00";
Start.Enabled = true;
Stop.Enabled = false;
}
Reading the file.
Now that we have the data stored in a file, we want to use it. In our case we are going to read the data in from the file, then display it in a DataGridView. In this application, when the user wants to see the data for a given date range, they enter that date range, then hit the All button. When the user does that, we read the data from the file and load that data into a DataTable, then bind our DataGridView to the populated DataTable.
private void PopulateTable(DataTable dtDataTable)
{
string contents;
int tabSize = 4;
string[] arInfo;
string line;
DataRow row;
try
{
string FILENAME = datafile;
StreamReader objStreamReader;
objStreamReader = File.OpenText(FILENAME);
while ((line = objStreamReader.ReadLine()) != null)
{
contents = line;
char[] textdelimiter = { '^' };
arInfo = contents.Split(textdelimiter);
for (int i = 0; i <= arInfo.Length; i++)
{
row = dtDataTable.NewRow();
if ((i < arInfo.Length) && (arInfo[i].ToString() != null))
{
row["Date"] = DateTime.Parse(arInfo[0].ToString());
}
if (i + 1 < arInfo.Length)
{
row["Code"] = arInfo[1].ToString();
}
if (i + 2 < arInfo.Length)
{
row["Ticket"] = arInfo[2].ToString();
}
if(i + 3 < arInfo.Length)
{
double dbDuration = Double.Parse(arInfo[3].ToString());
string strDuration = string.Format("{0:F2}", dbDuration);
row["Duration in minutes"] = strDuration;
dtDataTable.Rows.Add(row);
}
i = i + 2;
}
}
objStreamReader.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Points of Interest
In this application we made use of timers to update a label and make a functioning digital clock. In practice, you may think of a million things you can do with this simple yet powerful tool, from prompting users at a regular interval, to periodically checking the environment for new information.
History
Initial Revision.