我制作了一个简单的倒计时器,但当我在文本框中输入-1 : 59 : 59
时,计时器变为负0 : 0 : 0
。我尝试输入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: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;
}
}
答案 1 :(得分:0)
你的代码正在完全按照你要求它去做的,问题是你没有处理从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);
}
}
然后你可能会更好地设置定时器以更快地开火。也许是每半秒或每四分之一秒,这样显示器永远不会超过那么多。
答案 2 :(得分:0)
你没有检查何时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
}