代码之家  ›  专栏  ›  技术社区  ›  Mark Dickinson

假人的Winforms计时器

  •  16
  • Mark Dickinson  · 技术社区  · 16 年前

    我正试图让计时器在WinForm中每秒勾选一次,当我寻找如何做到这一点的建议时,我会找到很多关于线程的东西。我不在乎线程,因为我只想让一个值在一分钟内从60倒数到0,然后停止。我不认为我们需要进入云计算来解决这个问题,但我真的是一个web表单BOD,所以我对这个问题有点生疏。有人能给我举个例子吗

    这是我试过的

    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;
    }
    

    任何帮助都将不胜感激。

    4 回复  |  直到 16 年前
        1
  •  8
  •   jasonh    16 年前

    所发生的是你正在减少 timeLeft 变量,直到计时器的第一个刻度达到零。拿出 do...while 循环,你会得到一个基本的工作示例。

    但是,如果要执行任何数量的Windows窗体工作,则需要了解线程以及线程对UI的影响。如果您不了解无用的异常和行为不当的UI组件的故事,您很快就会发现自己回到这里。乔恩·斯基特有一个优秀的 threading series . 我强烈推荐。它有一个专门介绍计时器的部分,这样可以给您一些额外的见解。

        2
  •  8
  •   chakrit Dutchie432    16 年前

    不要 如果使用winforms的计时器,则需要线程。

    将计时器控件放到页面上,将其命名为“Timer”,然后粘贴以下代码:

    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();
        }
    }
    

    我想如果你来自一个网络背景,事件驱动的编程可能是你需要开始阅读的东西,如果你想了解桌面上的东西是如何编程的。

        3
  •  3
  •   Henk Holterman    16 年前

    除了取消循环(根据Jasonh的回答),如果应用程序有点忙,您的方法可能会变得有点不准确。虽然您以毫秒为单位指定时间间隔,但Winforms计时器的分辨率为18毫秒,优先级非常低,但是消息循环仅在发现没有其他功能时检查计时器。

    所以,保留starttime(datetime)值,并使用它计算每个计时器事件中的剩余时间。你只要打61勾就够了。

        4
  •  2
  •   Michael Petrotta user3140870    16 年前

    您不希望在事件处理程序中执行任何循环。这个处理程序在每一个计时器的“tick”中调用一次,正如您所配置的那样,每1000毫秒调用一次。所以你想减少你的 timeLeft 每次调用一次变量,然后在 泰利莱夫 命中为零。

    // 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;
        }
    }