I'm trying to get a timer to tick once a second in a winform, when I look for advice on how to do this I find loads of stuff about threads. Well I don't care about threads, because all I'm trying to do is make a value count down from 60 to 0 in one minute, then stop. I don't think we need to go into cloud computing to solve this one, but I am really a web forms bod, so I'm a bit rusty on this issue. Can anyone point me to an example
Here's what I tried
private void button1_Click(object sender, EventArgs e)
{
this.timeLeft = 60;
this.label1.Visible = false;
this.button1.Visible = false;
gt = new Timer();
gt.Tick += new EventHandler(CountDown);
gt.Interval = 1000;
gt.Start();
}
private void CountDown(object sender, EventArgs e)
{
do
{
this.TimeBar.Value = timeLeft;
this.timeLeft -= 1;
} while (this.timeLeft > 0);
if (this.TimeBar.Value > 0) return;
gt.Stop();
this.label1.Visible = true;
this.button1.Visible = true;
}
Any help would be appreciated.
You don't need threading if you use the winforms' timer.
Drop a Timer control on your page, name it "timer" and paste the following code:
public MainForm()
{
InitializeComponent();
timer.Interval = 1000;
timer.Start();
timeLeft = 60;
timer.Tick += Timer_Tick;
// start things
label1.Hide();
button1.Hide();
timer.Start();
}
public void Timer_Tick(object sender, EventArgs e)
{
timeLeft--;
if (timeLeft <= 0) {
timer.Stop();
label1.Show();
button1.Show();
}
}
I suppose if you've come from a webby background, Events-driven programming is probably the thing you need to get start reading about if you want to understand how stuff on the desktops are programmed.
What's happening is that you're decrementing the timeLeft
variable until it reaches zero on the very first tick of the timer. Take out the do...while
loop and you'd have a basically working example.
However if you're going to be doing any amount of Windows Forms work, you need to learn about threading and how that affects the UI. You'll very quickly find yourself back here if you don't with tales of unhelpful exceptions and misbehaving UI components. Jon Skeet has an excellent threading series. I highly recommend it. It has a section devoted to timers, so that might give you some additional insight.
Apart from taking out the loop (as per jasonh's answer), your approach could become a little inaccurate if the app is kind of busy. Although you specify their interval in milliseconds, WinForms timers have a 18 ms resolution and have a very low priority, the message loop only checks timers if it finds nothing else to do.
So, keep a StartTime (DateTime) value and use that to calculate the remaining time in every Timer event. You just could need 61 tick to reach a minute.
You don't want to do any looping in your event handler. The handler is called once per timer 'tick' - every 1000 milliseconds, as you've configured it. So you want to decrement your timeLeft
variable once per call, then shut the whole thing down when timeLeft
hits zero.
// untested
private void CountDown(object sender, EventArgs e)
{
this.TimeBar.Value = timeLeft;
this.timeLeft--;
if (this.TimeBar.Value == 0)
{
gt.Stop();
this.label1.Visible = true;
this.button1.Visible = true;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With