多个计时器似乎不适用于Windows窗体?

时间:2017-05-11 18:30:13

标签: c# .net winforms countdown

我有一个关于Windows窗体的问题。我做了这个倒计时,可以在下面的代码和图片上看到。我有一个问题。当我开始第一次倒计时开始和停止时,它以小时,分钟和秒的方式运行,但是一旦我运行第二次,第一次将值重置为放入第二次的值?它在它们两个上都跳过了一秒钟。所以它从第二个53到51在第一个和52到50在另一个..你们中的任何人有任何想法如何解决这个问题并使它们独立他们现在明显是彼此的?

提前谢谢!

namespace newtime
{
    public partial class Form1 : Form
    {
        private int h;
        private int m;
        private int s;
        public Form1()
        {
            InitializeComponent();
        }

        private void btnStart1_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!", "Timer");
            }
            string hh = Convert.ToString(h);
            string mm = Convert.ToString(m);
            string ss = Convert.ToString(s);
            textBox1.Text = hh;
            textBox2.Text = mm;
            textBox3.Text = ss;
        }

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

        private void btnStart2_Click(object sender, EventArgs e)
        {

            if (textBox4.Text == "")
            {
                textBox4.Text = "0";
            }
            if (textBox5.Text == "")
            {
                textBox5.Text = "0";
            }
            if (textBox6.Text == "")
            {
                textBox6.Text = "0";
            }
            h = Convert.ToInt32(textBox4.Text);
            m = Convert.ToInt32(textBox5.Text);
            s = Convert.ToInt32(textBox6.Text);
            timer2.Start();
        }

        private void timer2_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)
            {
                timer2.Stop();
                MessageBox.Show("Times up!", "Timer");
            }

            string hh = Convert.ToString(h);
            string mm = Convert.ToString(m);
            string ss = Convert.ToString(s);
            textBox4.Text = hh;
            textBox5.Text = mm;
            textBox6.Text = ss;
        }

        private void btnStop2_Click(object sender, EventArgs e)
        {
            timer2.Stop();
        }
    }
}

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:1)

正如其他海报所指出的那样,您只有hms的一个副本,这些副本由所有计时器事件处理程序共享。这意味着他们将覆盖彼此'你正在看的工作。显而易见的解决方法是为每个计时器创建hms的不同副本。

但是,我想指出您只能使用一个计时器解决此问题。该程序只需记录用户点击每个时间(从System.DateTime.Now获得)"开始"按钮并将其存储在变量中(每个计时器显示一个)。然后,在持续的基础上,它只需要计算当前时间和每个(存储的)开始时间之间的差异。正在进行的行为可以由单个计时器和循环触发。

最好避免在应用程序中运行很多不同的计时器,因为这样你就不必担心每个计时器的启动,停止和处理。

这是一个粗略的草稿,可以给你一个想法,它可能需要一两个调整来编译。

struct TimerStatus
{
    DateTime StartTime;
    bool IsRunning;
}

TimerStatus[] _timers = new TimerStatus[10];


void Start1_Click()
{
    _timers[1].StartTime = System.DateTime.Now;
    _timers[1].IsRunning = true;
}

void Stop1_Click()
{
    _timers[1].IsRunning = false;
}

void Start2_Click()
{
    _timers[2].StartTime = System.DateTime.Now;
    _timers[2].IsRunning = true;
}

void Stop2_Click()
{
    _timers[2].IsRunning = false;
}

void OneAndOnlyTimer_Tick()
{
    for (int i=0; i<=_timers.GetUpperBound(0); i++)
    {
        if (_timers[i].IsActive) 
        {
            TimeSpan ts = System.DateTime.Now - _timers[i].StartTime;
            DisplayTimer(i, ts.Hours, ts.Minutes, ts.Seconds);  //You will need to write the method that does the display
        }
    }
}

对于额外的功劳,你甚至可以对所有按钮使用相同的点击处理程序(你可以使用控件的Tag属性来识别数组索引)。但这超出了我的答案范围。