【问题标题】:Adding time to timer with button click通过单击按钮将时间添加到计时器
【发布时间】:2017-05-12 08:25:36
【问题描述】:

我设置了一个计时器,但不知道如何通过使用按钮分别添加 10 秒、1 分钟和 10 分钟来添加时间。我不确定我是否设法让它正确倒计时,因为我从一个计时的计时器中复制了代码并试图反转它。任何帮助将非常感激。 这是我的代码:

    int Ten_Sec = 10000;
    int One_Min = 60000;
    int Ten_Min = 600000;
    System.Timers.Timer t ;
    int hour, min, sec;

    private void Form1_Load(object sender, EventArgs e)
    {
        t = new System.Timers.Timer();
        t.Interval = 1000; //1sec
        t.Elapsed -= OnTimeEvent;
    }

    private void Button_Ten_Sec_Click_1(object sender, EventArgs e)
    {
        Ten_Sec++;
    }

    private void Button_One_Min_Click_1(object sender, EventArgs e)
    {
        One_Min++;
    }

    private void Button_Ten_Min_Click_1(object sender, EventArgs e)
    {
        Ten_Min++;
    }

    private void OnTimeEvent(object sender, ElapsedEventArgs e)
    {
        Invoke (new Action(() =>
        {
            sec -= 1;

            if (sec == 60)
            {
                sec = 0;
                min -= 1;
            }

            if (min == 60)
            {
                min = 0;
                hour -= 1;
            }

            textBox_Timer.Text = String.Format("{0},{1},{2}", hour.ToString().PadLeft(2, '0'), min.ToString().PadLeft(2, '0'), sec.ToString().PadLeft(2, '0'));


        }));
    }

【问题讨论】:

  • 看起来您正在取消订阅 Form_Load 中的 OnTimeEvent...这是故意的吗?
  • 老实说,这并不是我看到的用于制作计数计时器的代码
  • 以我的回答为例。
  • @ephtee 如何防止计时器超过零(负)或让它让我在特定时间间隔执行操作?

标签: c# winforms visual-studio


【解决方案1】:

有一些关于定时器的基本知识:

  1. 它有一个Tick 事件(或Elapsed 事件,取决于您使用的计时器)。它定期引发此事件。您可以为该事件订阅一个或多个方法,它们会定期触发
  2. 它有一个Interval - 这是它在引发Tick 事件之前等待的毫秒数。
  3. 它有一个Enabled 属性。如果设置为 false,则计时器未运行。
  4. 它有一个Start 方法。调用此方法启动计时器。它还有一个Stop 方法,您可以在希望它停止时调用该方法。这些方法也设置了Enabled属性,所以如果你调用Stop,那么Enabled会被设置为false

从上到下查看您的代码,我要做的第一件事就是摆脱这些变量。他们什么都不做,TimeSpan 类已经有一种简单的方法来指定分钟数或秒数:

// We don't need these
int Ten_Sec = 10000;
int One_Min = 60000;
int Ten_Min = 600000;

另外,您正在使用System.Timers.Timer,这可能会在尝试更新控制文本时引起一些麻烦,因为它在另一个线程中运行。相反,让我们使用System.Windows.Forms.Timer

public partial class Form1 : Form
{
    System.Windows.Forms.Timer timer;

我们还可以使用一个变量来保存我们正在显示的时间。如果我们将其设为类级变量,那么我们可以通过计时器的Tick 事件以及用户单击的按钮来更改它:

public partial class Form1 : Form
{
    System.Windows.Forms.Timer timer;
    TimeSpan countdownClock = TimeSpan.Zero;

现在,在您的 Form_Load 中,您正在做正确的事情,除了您从计时器中取消订阅 OnTimeEvent。如果有的话,我们应该订阅这个事件,所以我们有一些代码可以在计时器结束时执行。

另外请注意,我将您的计时器从 t 重命名为 timer。它提高了可读性并且不会真正减慢编码速度,因为只要您键入 t,Visual Studio 就会提供智能感知。并且我使用TimeSpan.FromSeconds的方法设置了定时器的间隔,这样可以更明显的看出间隔是什么:

private void Form1_Load(object sender, EventArgs e)
{
    timer = new System.Windows.Forms.Timer();
    timer.Interval = (int) TimeSpan.FromSeconds(1).TotalMilliseconds;
    timer.Tick += OnTimeEvent;
    DisplayTime();
}

您可能想知道DisplayTime() 有什么用。我写了一个小函数来显示表单上的时间,因为我们从不止一个地方做它并且它有一个特定的格式字符串。既然这是在一个地方完成的,如果你想改变格式,只有一个地方可以改变代码。

另外,我注意到您使用TextBox 来显示时间,但对于只读值,使用Label 可能更好。我创建了一个名为lblTime

private void DisplayTime()
{
    lblTime.Text = countdownClock.ToString(@"hh\:mm\:ss");
}

现在,回答您的一个主要问题:当计时器到达0 时,我们如何停止计时器?我们可以在OnTimeEvent 事件中执行此操作,因为这是计时器读取当前倒计时时钟并从中删除一秒的时刻。

请注意,此方法的签名与您的稍有不同。由于我使用的是不同类型的计时器,因此要求不同:

private void OnTimeEvent(object sender, EventArgs e)
{
    // Subtract whatever our interval is from the countdownClock
    countdownClock = countdownClock.Subtract(TimeSpan.FromMilliseconds(timer.Interval));

    if (countdownClock.TotalMilliseconds <= 0)
    {
        // Countdown clock has run out, so set it to zero 
        // (in case it's negative), and stop our timer
        countdownClock = TimeSpan.Zero;
        timer.Stop();
    }

    // Display the current time
    DisplayTime();
}

所以唯一剩下要做的就是启用计时器。由于我们从0 开始,因此没有地方可以倒计时,但您的表单上似乎有一些按钮可以为时钟添加时间,所以让我们使用这些按钮。

因为我们要从多个地方更新时间,而且这还需要检查计时器是否被禁用,如果不是则启动它,我创建了一个辅助方法来为时钟添加时间:

private void AddTimeToClock(TimeSpan timeToAdd)
{
    // Add time to our clock
    countdownClock += timeToAdd;

    // Display the new time
    DisplayTime();

    // Start the timer if it's stopped
    if (!timer.Enabled) timer.Start();
}

现在,我们将在每个按钮中调用该函数,根据按下的按钮传递不同的时间跨度:

private void Button_Ten_Sec_Click(object sender, EventArgs e)
{
    // Add ten seconds to our clock
    AddTimeToClock(TimeSpan.FromSeconds(10));
}

private void Button_One_Min_Click(object sender, EventArgs e)
{
    // Add one minute to our clock
    AddTimeToClock(TimeSpan.FromMinutes(1));
}

private void Button_Ten_Min_Click(object sender, EventArgs e)
{
    // Add ten minutes to our clock
    AddTimeToClock(TimeSpan.FromMinutes(10));
}

希望这足以让您继续前进。您现在有一个倒数计时器,当它到达0 时会停止,您可以通过按钮添加时间。

【讨论】:

  • 传奇人物,我非常感谢,这意味着我几乎可以完成我的程序
  • 有一个错误,即为时钟添加时间时没有显示初始时间,我只是在AddTimeToClock 方法中修复了这个错误(在启动计时器之前只需调用DisplayTime
  • 说我想减少计时器执行之间的时间(即有效地使倒计时运行得更快)我该怎么做?我玩过 timer.Interval 线,但似乎无法弄清楚
  • 重新阅读答案,它包含您需要的所有信息。除非您的意思是要以不同的方式显示时间,例如显示毫秒?
  • Interval 设置为您希望它在触发Tick 事件之前等待的毫秒数。如果要使间隔小于一秒,则需要显示毫秒。这可以通过在我们显示时间的格式字符串的末尾添加\.ffff 来完成。您可以使用 1-7 个f 字符,指定要显示的毫秒数。我不知道你所说的“右边的东西”是什么意思。
【解决方案2】:

我会看看DateTimeTimeSpan 结构。您可以操纵它们以输出您想要的任何时间,以及从中添加和减去时间。鉴于您的示例,您可能希望使用TimeSpan

    TimeSpan testTime = DateTime.Now.TimeOfDay;
    public Form1()
    {
        InitializeComponent();
        timer1.Enabled = true;
        timer1.Interval = 1000;
        timer1.Start();

    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        testTime = testTime.Subtract(new TimeSpan(0, 0, 1));
        lblTime.Text = testTime.ToString("hh\\:mm\\:ss");
    }

    private void button1_Click(object sender, EventArgs e)
    {
        testTime = testTime.Add(new TimeSpan(1, 0, 0));
        lblTime.Text = testTime.ToString("hh\\:mm\\:ss");
    }

    private void button2_Click(object sender, EventArgs e)
    {
        testTime = testTime.Add(new TimeSpan(0, 1, 0));
        lblTime.Text = testTime.ToString("hh\\:mm\\:ss");
    }

    private void button3_Click(object sender, EventArgs e)
    {
        testTime = testTime.Add(new TimeSpan(0, 0, 1));
        lblTime.Text = testTime.ToString("hh\\:mm\\:ss");
    }

结果如下:

【讨论】:

    猜你喜欢
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 2019-06-24
    • 1970-01-01
    相关资源
    最近更新 更多