倒数计时器进入负数 (00:00:00)

Countdown timer goes into negative number (00:00:00)

我制作了一个简单的倒数计时器,但当我在文本框上输入 0 : 0 : 0 时,计时器变为负值 -1 : 59 : 59。我尝试输入 0 : 0 : 1,计时器停在 0 : 0 : 0,消息框出现在屏幕上

我已经尝试使用此代码来防止出现负值,但它停在 -1 : 59 : 58

if (label1.Text == "-1")
{
    timer1.Stop()
}

尝试了此代码,但它在 -1 : 59 : 59

处停止
if (h < 0)
{
    timer1.Stop();
}

这是代码

namespace Timer
{

    public partial class Form1 : Form
    {

        int h;
        int m;
        int s;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text == "")
            {
                textBox1.Text = "0";
            }
            if (textBox2.Text == "")
            {
                textBox2.Text = "0";
            }
            if (textBox3.Text == "")
            {
                textBox3.Text = "0";
            }

            h = Convert.ToInt32(textBox1.Text);
            m = Convert.ToInt32(textBox2.Text);
            s = Convert.ToInt32(textBox3.Text);

            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            s = s - 1;

            if(s == -1)
            {
                m = m - 1;
                s = 59;
            }

            if (m == -1)
            {
                h = h - 1;
                m = 59;
            }
            if (h == 0 && m == 0 && s == 0)
            {
                timer1.Stop();
                MessageBox.Show("Times up!", "Time");
            }

            string hh = Convert.ToString(h);
            string mm = Convert.ToString(m);
            string ss = Convert.ToString(s);

            label1.Text = hh;
            label2.Text = mm;
            label3.Text = ss;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            timer1.Stop();
        }
    }
}

您没有涵盖提供 0:0:0 的情况。 替换为:

        s = s - 1;

        if(s == -1)
        {
            m = m - 1;
            s = 59;
        }

        if (m == -1)
        {
            h = h - 1;
            m = 59;
        }

有了这个:

if(s > 0 || m > 0 || h > 0)
{
            s = s - 1;
            if(s == -1)
            {
                m = m - 1;
                s = 59;
            }

            if (m == -1)
            {
                h = h - 1;
                m = 59;
            }
}

您的代码完全按照您的要求执行,问题是您没有处理从 0:0:0 开始的 边缘情况

我认为这将被视为无效输入,因此处理此问题的最简单方法可能是在您点击按钮启动计时器之前进行检查:

        h = Convert.ToInt32(textBox1.Text);
        m = Convert.ToInt32(textBox2.Text);
        s = Convert.ToInt32(textBox3.Text);

        // one of these must be non-zero
        if (h != 0 || m != 0 || s != 0)
        {
            timer1.Start();
        }
        else
        {
            // handle this how ever you want but you don't need to start a timer
            // and really shouldn't start the timer
        }

如果用户输入全部为零,让计时器计时实际上是错误的,因为当他们要求 0 秒时,他们会得到 1 秒。

更好的方法是在输入非零时间之前实际禁用该按钮。为此,我建议将 TextBox 替换为 NumericUpDown(因为无论如何只有数字输入有效),然后为其 ValueChanged 事件添加处理程序。在该处理程序中,三个控件中的任何一个都具有非零值,如果有,则启用该按钮。如果它们都为零,则禁用该按钮。

这里有一个重要的旁白 - System.Windows.Forms.Timer 不是特别准确,所以不要指望设置为每 1 秒计时一次的计时器实际上是每秒计时一次。每次滴答之间至少 1 秒,但通常会多几毫秒。所以你的倒计时会漂移。如果您将其设置为倒计时 1 分钟(即 60 秒),如果倒计时实际上需要 62 秒,请不要感到惊讶。如果这对您很重要,那么您应该在启动计时器时记录当前时间,然后检查当前时间与启动计时器时间之间的差异,并使用它来更新标签。

更好的整体解决方案可能如下所示:

DateTime end;

private void button1_Click(object sender, EventArgs e)
{
    var h = hourNumericUpDown.Value;
    var m = minuteNumericUpDown.Value;
    var s = secondsNumericUpDown.Value;
    if (h != 0 || m != 0 || s != 0)
    {
        var start = DateTime.Now;
        var timeSpan = new TimeSpan(0,h,m,s);
        end = start.Add(timeSpan);
        countDownLabel.Text = timeSpan.ToString();  
        timer1.Start();
    }
}

private void timer1_Tick(object sender, EventArgs e)
{
    var timeleft = end - DateTime.Now;
    if (timeLeft.Ticks < 0) 
    {
        countDownLabel.Text = "00:00:00";
        timer1.Stop();
        MessageBox.Show("Times up!", "Time");
    }
    else 
    {
        countDownLabel.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", 
            timeLeft.Hours, timeLeft.Minutes, timeLeft.Seconds);
    }
}

然后您最好将计时器设置为更快启动。也许每半秒或每四分之一秒,这样显示器就不会关闭超过那么多。

当h变为负数时你没有检查,我已经添加了一个你可以添加你的。

 if (s == -1)
        {
            m = m - 1;
            s = 59;
        }

        if (m == -1)
        {
            h = h - 1;
            m = 59;
        }
        /*I added such condition*/
        if(h < 0)
        {
            h = 0;
            m = 0;
            s = 0;
        }
        if (h == 0 && m == 0 && s == 0)
        {
            timer1.Stop();
            MessageBox.Show("Times up!", "Time");
            return;//return early
        }