Search code examples
c#winformstimer

Countdown timer with numericupdown


In a Winforms application, there are 3 different numericupdown such as min, sec, millisecond. How do I make a timer that counts down the value of entering numericupdowns? I have tried with if else blocks. I also saw a lot of time timespawn titles on the internet. Which is better for this countdown? if else blocks or timespawn

numericUpDownMiliSn.Value--;

if (numericUpDownMiliSn.Value == 0)
{
    if (numericUpDownMiliSn.Value == 0 && numericUpDownSn.Value == 0 && numericUpDownDk.Value == 0)
    {
        timer2.Stop();
        button2.Text = "Baslat";
        durum = false;
    }
    else
    {
        if (numericUpDownSn.Value > 0)
        {
            numericUpDownSn.Value--;
            numericUpDownMiliSn.Value = 60;
        }
        else
        {
            numericUpDownMiliSn.Value = 60;
        }

        if (numericUpDownSn.Value > 0)
        {
            numericUpDownSn.Value--;
            numericUpDownSn.Value = 60;
        }
    }
}

Solution

  • From my comments in the original question above:

    Timers in WinForms are NOT accurate, so you shouldn't be basing your time off incrementing/decrementing those in a Tick() event. You should definitely be using a TimeSpan (derived from subtracting the current time from some future target time; based on the initial values in your NumericUpDowns)...then simply update the NumericUpDowns with the numbers in the TimeSpan.

    Here's how that code might look:

    private DateTime targetDT;
    
    private void button1_Click(object sender, EventArgs e)
    {
        TimeSpan ts = new TimeSpan(0, 0, (int)numericUpDownMn.Value, (int)numericUpDownSn.Value, (int)numericUpDownMiliSn.Value);
        if (ts.TotalMilliseconds > 0)
        {
            button1.Enabled = false;
            numericUpDownMn.Enabled = false;
            numericUpDownSn.Enabled = false;
            numericUpDownMiliSn.Enabled = false;
            targetDT = DateTime.Now.Add(ts);
            timer1.Start();
        }
    }
    
    private void timer1_Tick(object sender, EventArgs e)
    {
        TimeSpan ts = targetDT.Subtract(DateTime.Now);
        if (ts.TotalMilliseconds > 0)
        {
            numericUpDownMn.Value = ts.Minutes;
            numericUpDownSn.Value = ts.Seconds;
            numericUpDownMiliSn.Value = ts.Milliseconds;
        }
        else
        {
            timer1.Stop();
            numericUpDownMn.Value = 0;
            numericUpDownSn.Value = 0;
            numericUpDownMiliSn.Value = 0;
            button1.Enabled = true;
            numericUpDownMn.Enabled = true;
            numericUpDownSn.Enabled = true;
            numericUpDownMiliSn.Enabled = true;
        }
    }