表单计时器不启动

Form timer doesn't start

所以我刚开始学习 C# 和使用表单。我已经能够创建一个数字时钟并对此进行修补,但现在我正在尝试为 derpy 游戏制作一个基本的 UI,但我的计时器不起作用。

首先 - 我想要完成的事情:一个从 60 秒开始的简单递减计时器(*时钟样式 (mm:ss))。
其次,这是我所拥有的:

public partial class Form1 : Form
{
    private int counter = 60;
    public Form1()
    {
        InitializeComponent();
        label1.Text = TimeSpan.FromMinutes(1).ToString("m\:ss");
    }

    private void pictureBox2_Click(object sender, EventArgs e)
    {

    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        counter--;
        if (counter == 0)
        {
            timer1.Stop();
            label1.Text = counter.ToString();
            MessageBox.Show("Time's Up!!");
        }
    }

    private void label1_Click(object sender, EventArgs e)
    {
        var startTime = DateTime.Now;
        var counter = (TimeSpan.FromMinutes(1)).ToString("m\:ss");
        timer1 = new Timer();
        timer1.Tick += new EventHandler(timer1_Tick);
        timer1.Interval = 1000;
        timer1.Start();
        label1.Text = counter.ToString();
    }
}

感谢反馈和知识!

这对我来说很好用。我会在时间倒计时时提供进度更新,以表明它正在运行。例如,如果您在标签中执行此操作,则可以执行如下操作:

private void timer1_Tick(object sender, EventArgs e)
{
    counter--;
    label1.Text = counter.ToString();
    if (counter == 0)
    {
        timer1.Stop();
        MessageBox.Show("Time's Up!!");
    }
}

请注意,label1.Text = counter.ToString(); 行已移至 counter == 0 检查之前,以便它能够为所有计数器值提供反馈。

同样,如果您不跟踪使用 new Timer() 生成的数量,您可能会意外启动多个 timer1 实例。有多种方法可以做到这一点,但您可以在创建新实例之前简单地检查 timer1counter == 0 是否已经存在。您可以将此检查作为保护子句执行(即 return 如果这些条件中的任何一个匹配)。

private void label1_Click(object sender, EventArgs e)
{
    var startTime = DateTime.Now;
    if (timer1 == null || (timer1 != null && counter == 0)) return;
    counter = (TimeSpan.FromMinutes(1)).ToString("m\:ss");
    timer1 = new Timer();
    timer1.Tick += new EventHandler(timer1_Tick);
    timer1.Interval = 1000;
    timer1.Start();
    label1.Text = counter.ToString();
}

如果你想让这个倒计时自动开始,你可以直接把它放在构造函数中,或者把它放在另一个方法中,然后从构造函数中调用它:

public Form1()
{
    InitializeComponent();
    StartCountdown();
}

private void StartCountdown()
{
    var startTime = DateTime.Now;
    /* the rest of your original label1_Click code goes here ... */
}

根据我看到的代码,您的计时器正在工作,但您没有在每次计数时更新它,而是在计时器结束时更新 -

private void timer1_Tick(object sender, EventArgs e)
{
    counter--;
    if (counter == 0)
    {
        timer1.Stop();
        label1.Text = counter.ToString(); // *** Look here
        MessageBox.Show("Time's Up!!");
    }
}

你应该在每个滴答中更新计时器,所以从 if 块中取出更新标签代码 -

private void timer1_Tick(object sender, EventArgs e)
{
    counter--;
    label1.Text = counter.ToString(); // should work
    if (counter == 0)
    {
        timer1.Stop();
        MessageBox.Show("Time's Up!!");
    }
}

并在每个循环中重置计数器 -

private void label1_Click(object sender, EventArgs e)
{
    var startTime = DateTime.Now;

    var counter = (TimeSpan.FromMinutes(1)).ToString("m\:ss");
    timer1 = new Timer();
    timer1.Tick += new EventHandler(timer1_Tick);
    timer1.Interval = 1000;
    timer1.Start();
    label1.Text = counter.ToString();
    this.counter = 60
}

NOTE: I am really not sure if this code will throw any access violation error, due to updating the UI in a different thread or not. If so, then you have to use async/await or events/delegates to update UI.

Let me know, if this throws error, then I will give you the async/await version.