如何使倒数计时器即使在 Winform 关闭时也能继续?

匿名
2024-03-11T08:17:37.7833333+00:00

你好。我是 Windows 窗体的新手,所以我不太了解事情是如何工作的。最近,我尝试制作一个倒数计时器,从某个时间数到 0。但是当表格关闭时,一切都像“重置”,我不希望这样。例如,我想要的是倒计时时间是 5 分钟 -> 关闭表格 -> 3 分钟后打开表格 ->倒计时时间还剩 2 分钟。我想知道你们是否可以分享任何可以使它起作用并且简单的想法,以便我能够理解.提前致谢!

Note:此问题总结整理于:How to make a countdown Timer continue even when Winform is closed?

开发人员技术 | Windows 窗体
开发人员技术 | C#
0 个注释 无注释
{count} 票

接受的答案
  1. Hui Liu-MSFT 48,676 信誉分 Microsoft 外部员工
    2024-03-11T09:18:31.2866667+00:00

    欢迎来到Microsoft问答,根据你的描述,你想做一个倒数计时器,并希望它在表格关闭时会持续。

    我做了一些步骤和代码示例。您可以检查它是否适合您。

    首先,我根据答案制作一个倒数计时器。

    其次,我在 winform 中添加以下设置。

    200800-image.png

    第三,我使用 FormClosing 事件将一些信息保存到设置中。

      private void Form1_FormClosing(object sender, FormClosingEventArgs e)  
            {  
                if(timer.IsRunnign)  
                {  
                    Properties.Settings.Default.lefttime = label1.Text;  
                    Properties.Settings.Default.Isrunning = true;  
                    Properties.Settings.Default.closedtime=DateTime.Now;  
                    Properties.Settings.Default.Save();  
                }  
            }  
      
     Fourth, I used Form1_Load event to read the information.  
      
      private void Form1_Load(object sender, EventArgs e)  
            {  
                if (Properties.Settings.Default.Isrunning== true)  
                {  
                    string lefttime = Properties.Settings.Default.lefttime;  
                    TimeSpan time1=TimeSpan.ParseExact(lefttime, @"mm\:ss", CultureInfo.CurrentCulture);  
                    DateTime closedtime = Properties.Settings.Default.closedtime;  
                    TimeSpan passedtime = DateTime.Now - closedtime;  
                    var t = time1.Subtract(passedtime);  
                    label1.Text=t.ToString(@"mm\:ss");  
                    timer.SetTime(t.Minutes, t.Seconds);  
                    timer.Start();  
                    timer.TimeChanged += () => { label1.Text = timer.TimeLeftStr; };  
      
                    // show messageBox on timer = 00:00.000  
                    timer.CountDownFinished += () => { timer.Stop(); MessageBox.Show("Timer finished the work!"); };  
      
                    //timer step. By default is 1 second  
                    timer.StepMs = 1; // for nice milliseconds time switch  
                }  
                else  
                {  
                    //set to 5 mins  
                    timer.SetTime(5, 0);  
      
                    //update label text  
                    timer.TimeChanged += () => { label1.Text = timer.TimeLeftStr; };  
      
                    // show messageBox on timer = 00:00.000  
                    timer.CountDownFinished += () => { timer.Stop(); MessageBox.Show("Timer finished the work!"); };  
      
                    //timer step. By default is 1 second  
                    timer.StepMs = 1; // for nice milliseconds time switch  
                }  
                 
            }  
    

    最后,请在单击停止按钮时设置属性。

    完成的代码:

     public partial class Form1 : Form  
        {  
            public Form1()  
            {  
                InitializeComponent();  
            }  
            CountDownTimer timer = new CountDownTimer();  
            private void Form1_Load(object sender, EventArgs e)  
            {  
                if (Properties.Settings.Default.Isrunning== true)  
                {  
                    string lefttime = Properties.Settings.Default.lefttime;  
                    TimeSpan time1=TimeSpan.ParseExact(lefttime, @"mm\:ss", CultureInfo.CurrentCulture);  
                    DateTime closedtime = Properties.Settings.Default.closedtime;  
                    TimeSpan passedtime = DateTime.Now - closedtime;  
                    var t = time1.Subtract(passedtime);  
                    label1.Text=t.ToString(@"mm\:ss");  
                    timer.SetTime(t.Minutes, t.Seconds);  
                    timer.Start();  
                    timer.TimeChanged += () => { label1.Text = timer.TimeLeftStr; };  
      
                    // show messageBox on timer = 00:00.000  
                    timer.CountDownFinished += () => { timer.Stop(); MessageBox.Show("Timer finished the work!"); };  
      
                    //timer step. By default is 1 second  
                    timer.StepMs = 1; // for nice milliseconds time switch  
                }  
                else  
                {  
                    //set to 5 mins  
                    timer.SetTime(5, 0);  
      
                    //update label text  
                    timer.TimeChanged += () => { label1.Text = timer.TimeLeftStr; };  
      
                    // show messageBox on timer = 00:00.000  
                    timer.CountDownFinished += () => { timer.Stop(); MessageBox.Show("Timer finished the work!"); };  
      
                    //timer step. By default is 1 second  
                    timer.StepMs = 1; // for nice milliseconds time switch  
                    Console.WriteLine(Properties.Settings.Default.lefttime);  
                }  
                 
            }  
      
            private void button1_Click(object sender, EventArgs e)  
            {  
                timer.Start();  
            }  
      
            private void button2_Click(object sender, EventArgs e)  
            {  
                timer.Pause();  
            }  
      
            private void button3_Click(object sender, EventArgs e)  
            {  
                timer.Stop();  
                timer.Dispose();  
                Properties.Settings.Default.lefttime = "";  
                Properties.Settings.Default.Isrunning = false;  
                Properties.Settings.Default.closedtime = DateTime.Now;  
                Properties.Settings.Default.Save();  
            }  
      
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)  
            {  
                if(timer.IsRunnign)  
                {  
                    Properties.Settings.Default.lefttime = label1.Text;  
                    Properties.Settings.Default.Isrunning = true;  
                    Properties.Settings.Default.closedtime=DateTime.Now;  
                    Properties.Settings.Default.Save();  
                }  
            }  
        }  
        public class CountDownTimer : IDisposable  
        {  
            public Stopwatch _stpWatch = new Stopwatch();  
      
            public Action TimeChanged;  
            public Action CountDownFinished;  
      
            public bool IsRunnign => timer.Enabled;  
      
            public int StepMs  
            {  
                get => timer.Interval;  
                set => timer.Interval = value;  
            }  
      
            private Timer timer = new Timer();  
      
            private TimeSpan _max = TimeSpan.FromMilliseconds(30000);  
      
            public TimeSpan TimeLeft => (_max.TotalMilliseconds - _stpWatch.ElapsedMilliseconds) > 0 ? TimeSpan.FromMilliseconds(_max.TotalMilliseconds - _stpWatch.ElapsedMilliseconds) : TimeSpan.FromMilliseconds(0);  
      
            private bool _mustStop => (_max.TotalMilliseconds - _stpWatch.ElapsedMilliseconds) < 0;  
      
            public string TimeLeftStr => TimeLeft.ToString(@"mm\:ss");  
      
            public string TimeLeftMsStr => TimeLeft.ToString(@"mm\:ss\.fff");  
      
            private void TimerTick(object sender, EventArgs e)  
            {  
                TimeChanged?.Invoke();  
      
                if (_mustStop)  
                {  
                    CountDownFinished?.Invoke();  
                    _stpWatch.Stop();  
                    timer.Enabled = false;  
                }  
            }  
      
            public CountDownTimer(int min, int sec)  
            {  
                SetTime(min, sec);  
                Init();  
            }  
      
            public CountDownTimer(TimeSpan ts)  
            {  
                SetTime(ts);  
                Init();  
            }  
      
            public CountDownTimer()  
            {  
                Init();  
            }  
      
            private void Init()  
            {  
                StepMs = 1000;  
                timer.Tick += new EventHandler(TimerTick);  
            }  
      
            public void SetTime(TimeSpan ts)  
            {  
                _max = ts;  
                TimeChanged?.Invoke();  
            }  
      
            public void SetTime(int min, int sec = 0) => SetTime(TimeSpan.FromSeconds(min * 60 + sec));  
      
            public void Start()  
            {  
                timer.Start();  
                _stpWatch.Start();  
            }  
      
            public void Pause()  
            {  
                timer.Stop();  
                _stpWatch.Stop();  
            }  
      
            public void Stop()  
            {  
                Reset();  
                Pause();  
            }  
      
            public void Reset()  
            {  
                _stpWatch.Reset();  
            }  
      
            public void Restart()  
            {  
                _stpWatch.Reset();  
                timer.Start();  
            }  
      
            public void Dispose() => timer.Dispose();  
        }  
    

    测试结果:

    200921-3.gif

    如果答案是正确的,请点击“接受答案”并点赞。 如果您对此答案还有其他疑问,请点击“评论”。

    注意:如果您想接收相关电子邮件,请按照我们的文档中的步骤启用电子邮件通知 此线程的通知。

    1 个人认为此答案很有帮助。
    0 个注释 无注释

0 个其他答案

排序依据: 非常有帮助

你的答案

问题作者可以将答案标记为“接受的答案”,这有助于用户了解已解决作者问题的答案。