tags:

views:

1531

answers:

3

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.

+4  A: 

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.

jasonh
And don't forget to disable the timer after the countdown is over, otherwise you'll run into negative numbers.
Martinho Fernandes
Thanks, its quite late here, of course I don't need the loop, doh! Thanks also for the link to Mr Skeet's threading docs. :)
Mark Dickinson
@Martinho - Obligado, yeah that one got me too :)
Mark Dickinson
+1  A: 

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.

chakrit
Thanks, yeah the threading thing was just noise, I've got it sorted now, but I've also got some good reading pointers.
Mark Dickinson
+2  A: 

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;
    }
}
Michael Petrotta
Thanks, was just having a bit of brain fade, doing a little project for my daughter to use, due to poor TV here. Your code is pretty much what I ended up with.
Mark Dickinson