Reputation: 361
This is my first attempt at learning classes in any language. I am trying to create a Windows Form Project that is a stop watch. I've created a class that has a StartClock method that starts a stopwatch, I then put the elapsed time into a timespan variable. I then take a elapsedTime string and set it equal to a formatted string with the time span varibles. Code Below.
public class CStopWatch
{
Stopwatch sw = new Stopwatch();
private DateTime startTime;
private DateTime stopTime;
private String elapsedTime;
public String ElapsedTime
{
get
{
return elapsedTime;
}
}
public String StartClock()
{
sw.Start();
TimeSpan ts = sw.Elapsed;
elapsedTime = String.Format("{0:00}:{1:00}:{2:00}",
ts.Hours, ts.Minutes, ts.Seconds / 10);
return elapsedTime;
}
public void StopClock()
{
// sw.Stop();
}
}
On the Windows Form I call a new instance of my CStopwatch class and then on the start button click event I start my forms timer, call my StartClock method, and then set my time interval to every second.
In my Timer tick event I set my label to display the elapsed time string variable. When I run this I do not get any errors, but the label does not change. Below is my Windows Form Code.
public partial class Form1 : Form
{
// string elapsedTime;
// public string elapsedTime { get { return elapsedTime; } }
CStopWatch sw = new CStopWatch();
public Form1()
{
InitializeComponent();
}
private void lblTime_Click(object sender, EventArgs e)
{
}
private void btnStart_Click(object sender, EventArgs e)
{
timer.Enabled = true;
sw.StartClock();
timer.Interval = 1000;
//Testing without using classes
/*
timer.Enabled = true;
sw.Start();
timer.Interval = 1000;
TimeSpan ts = sw.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}",
ts.Hours, ts.Minutes, ts.Seconds / 10);
*/
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void timer_Tick(object sender, EventArgs e)
{
lblTime.Text = sw.ElapsedTime;
}
}
I'm sure I'm missing something or doing something stupid, but all my google fu has not lead me to the answer yet. Thanks in advance.
Upvotes: 3
Views: 84
Reputation: 17402
I believe there are some issues with your current implementation. Update your WinForms code-behind so that StartClock
happens after you set the Interval
. Also, if the Timer
is happening on another Thread, you will want to Invoke
the control. Lastly, you need to update the ElapsedTime
whenever the Tick occurs.
public partial class Form1 : Form
{
CStopWatch sw = new CStopWatch();
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
timer.Interval = 1000;
timer.Enabled = true;
lblTime.Text = sw.StartClock();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void timer_Tick(object sender, EventArgs e)
{
UpdateElapsedTime();
if (lblTime.InvokeRequired)
{
lblTime.Invoke(new MethodInvoker(() =>
{
lblTime.Text = sw.ElapsedTime;
}));
}
}
}
Then, you can update your CStopWatch class to have include an UpdateElapsedTime
method.
public class CStopWatch
{
private Stopwatch sw = new Stopwatch();
private DateTime startTime;
private DateTime stopTime;
private String elapsedTime;
public String ElapsedTime
{
get
{
return elapsedTime;
}
}
public String StartClock()
{
sw.Start();
UpdateElapsedTime();
return ElapsedTime;
}
public void UpdateElapsedTime()
{
TimeSpan ts = sw.Elapsed;
ElapsedTime = String.Format("{0:00}:{1:00}:{2:00}", ts.Hours, ts.Minutes, ts.Seconds / 10);
}
public void StopClock()
{
sw.Stop();
}
}
Upvotes: 1
Reputation: 5093
The problem is that you actually don't update your elapsedTime
variable. You can instead use your Stopwatch
in ElapsedTime
property:
public String ElapsedTime
{
get
{
return string.Format("{0:00}:{1:00}:{2:00}", sw.Elapsed.Hours, sw.Elapsed.Minutes, sw.Elapsed.Seconds / 10);
}
}
or equivalently (C# 6.0):
public String ElapsedTime => $"{sw.Elapsed.Hours:00}:{sw.Elapsed.Minutes:00}:{sw.Elapsed.Seconds/10:00}";
Upvotes: 0
Reputation: 18051
This is because elapsedTime is set once, then never updated.
public String ElapsedTime
{
get
{
return String.Format("{0:00}:{1:00}:{2:00}", sw.Elapsed);
}
}
This should fix it. So elapsedTime declaration and initialization are not useful and can be removed:
public class CStopWatch
{
Stopwatch sw = new Stopwatch();
public String ElapsedTime
{
get
{
return String.Format("{0:00}:{1:00}:{2:00}", sw.Elapsed);
}
}
public void StartClock()
{
sw.Start();
}
public void StopClock()
{
sw.Stop();
}
}
Upvotes: 1
Reputation: 7484
try the following
timer.Elapsed += OnTimedEvent;
timer.Interval = 1000;
timer.Enabled = true;
sw.StartClock();
Add the following method:
private static void OnTimedEvent(Object source, ElapsedEventArgs e)
{
lblTime.Text = string.Format("{0:HH:mm:ss.fff}",e.SignalTime);
}
Upvotes: 0
Reputation: 58
You assign value of variable elapsedTime only once after clicking on Start button. Later on you try to read value from it (using ElapsedTime property) in timer_Tick method however you do not assign new value. Try something like this:
public String ElapsedTime
{
get
{
TimeSpan ts = sw.Elapsed;
return String.Format("{0:00}:{1:00}:{2:00}",
ts.Hours, ts.Minutes, ts.Seconds / 10);
}
}
Upvotes: 3
Reputation: 21015
check out this , I think the timer tick event occurs on another thread, that not allowed to update the ui, the link shows solutions depends on which .net version you are using.
Upvotes: 0