【问题标题】:Use a Timer to increment a ProgressBar and show a count-down使用 Timer 增加 ProgressBar 并显示倒计时
【发布时间】:2021-08-13 18:12:52
【问题描述】:

我需要一些帮助来制作一个倒计时计时器,该计时器也会增加 ProgressBar。
我有一个按钮,它生成一个随机时间(以分钟表示),它将增加一个 ProgressBar,用作 loader 的一种形式。

当 ProgressBar 增加其值时,我想在标签中显示剩余时间。

这是我的代码:

int RandomNumber;
int MinutesElapsed;

private void button1_Click(object sender, EventArgs e)
{
    Random random = new Random((int)DateTime.Now.Ticks);
    RandomNumber = random.Next(1, 121); // at (x, x) there is a limit from x to x+1
    MinutesElapsed = 0;
    QuestTimer1.Start(); // starts the timer
}

private void QuestTimer1_Tick(object sender, EventArgs e)
{
    MinutesElapsed++;
    double minutes = MinutesElapsed / 1.2;
    progressBar1.Value = (int)minutes;
}

【问题讨论】:

  • 仅供参考 - 不要在每次单击按钮时初始化 new Random()。使用static readonly Random = new Random(); 字段并将其用作随机数生成器。
  • 那么,问题出在哪里?只需添加一个文本框并使用剩余时间进行更新?
  • @JonasH 这是我不知道怎么写的问题:D
  • 那么,你做了哪些研究?您尝试了哪些解决方案? Stackoverflow 不是免费的代码编写服务,预计比“我想做 X 请教我怎么做”付出更多的努力。
  • @JonasH 我试图研究相同的“剩余时间”计数器,但我遇到了一个实际上带有我拥有的标签的代码,我只需要重新制作代码以使其工作。所以我加入并粘贴它并进行了一些细微的更改,从 8 个错误下降到 3 个。所以我联系了我的朋友来帮助我,我向他们展示了代码和我的尝试。他们说是的,不应该还有更多。我向他们发送了我从中获得它的网站。现在我试着自己做,并想出了一个解决方案。我会在运行程序时更新问题并分享错误:)

标签: c# .net winforms timer progress-bar


【解决方案1】:

这可能看起来违反直觉,但在实现“计时器”时,不需要实际的计时器来保持时间。您当然不需要每秒钟设置一个计时器并增加一个变量——您的系统时钟已经这样做了!您的程序只需要知道开始时间、结束时间和当前时间,并且在任何给定时刻,都可以计算进度百分比和剩余时间。

当您开始流程时,记下当前时间并存储目标完​​成时间。

DateTime _startTime;
DateTime _endTime;

private void StartTimer_Click(object sender, EventArgs e)
{
    _startTime = DateTime.Now;
    var duration = random.Next(1, 121); 
    _endTime = _startTime.AddSeconds(duration);
}

然后,当您想知道剩余时间或进度时,计算它们:

public int SecondsRemaining => (_endTime - DateTime.Now).TotalSeconds;

public double PercentComplete => ((double)(_endTime - DateTime.Now).TotalMilliseconds) / (_endTime - _startTime).TotalMilliseconds;

您可以随时调用这些属性中的任何一个,它们将始终准确地为您提供完成百分比和剩余时间。您根本不需要单独的计时器!

但是,您可能希望不时更新显示。你需要一个计时器,但它可以在任何时间间隔运行,而且很容易编写:

void Timer_Tick(object sender, EventArgs e)
{
    this.TimeRemainingLabel.Text = SecondsRemaining.ToString() + " seconds";
    this.ProgressBar.Value = (int)(PercentComplete * 100);
}

【讨论】:

    【解决方案2】:

    一些可能有用的注释:
    你的按钮(你应该给它一个正确的名字)可以用来启动/停止计时器并生成一个新的随机数,代表分钟,使用Random对象(声明为静态字段 - 这里不是那么重要,但因为其内部功能,这种方式更可靠)。

    生成的随机值初始化一个 TimeSpan 对象 (totalTime),该对象存储总时间,以作为参考。
    您可以直接在 TimeSpan 构造函数中设置时间度量:如果值(此处以分钟表示)溢出正常度量(在本例中为 60 分钟),则 TimeSpan 类计算正确的值(即,如果您设置 Minutes 组件到构造函数中的90,TimeSpan 将自动计算 1 小时 30 分钟)。

    另一个 TimeSpan (minutesElapsed) 将存储经过的时间。

    计时器的Interval 设置为1000ms
    ProgrssBar 应保持其标准值范围:(0 - 100)
    您可以将其视为完成百分比。每次 Timer 滴答作响,我们都会调整总时间和经过时间之间的差异,将其压缩在这个值范围内。

    TimeSpan totalTime;
    TimeSpan minutesElapsed;
    static Random rnd = new Random();
    
    private void button1_Click(object sender, EventArgs e)
    {
        QuestTimer1.Stop();
        minutesElapsed = new TimeSpan(0, 0, 0);
        // 0 Hours, N Minutes, 0 Seconds
        totalTime = new TimeSpan(0, rnd.Next(1, 121), 0);
    
        lblTimeLeft.Text = totalTime.ToString(@"hh\:mm\:ss");
        QuestTimer1.Start();
    }
    

    计时器滴答声 - 1 秒过去了 - 因此将经过的时间增加一秒并计算总时间与当前经过的秒数之间的差。
    TimeSpan 对象支持常用运算符来执行加法和减法,并提供不同的属性来评估它们的值,单位为 Ticks、Milliseconds、Seconds 等。

    每秒钟更新一个标签(此处名为 lblTimeLeft),显示还剩多少秒(作为倒计时),而 ProgressBar 增加它的值。

    minutesElapsed >= totalTime时,定时器停止。

    private void QuestTimer1_Tick(object sender, EventArgs e)
    {
        minutesElapsed += TimeSpan.FromSeconds(1);
    
        lblTimeLeft.Text = (totalTime - minutesElapsed).ToString(@"hh\:mm\:ss");
        progressBar1.Value = (int)(minutesElapsed.TotalMinutes / totalTime.TotalMinutes * 100D);
    
        if (minutesElapsed.TotalMinutes >= totalTime.TotalMinutes) {
            QuestTimer1.Stop();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多