C# WinForm Upcounter 到 hh:mm:ss

Posted

技术标签:

【中文标题】C# WinForm Upcounter 到 hh:mm:ss【英文标题】:C# WinForm Upcounter to hh:mm:ss 【发布时间】:2021-12-02 05:04:13 【问题描述】:

我想编写一个像 OBS Studio 这样的程序,我想在我的程序中添加一个 Upcounter,这意味着当我点击“Start Stream”时,它应该从 00:00:00 到 00:00:01 启动 Upcounter 00:00:02 以此类推,这样我就有了“直播时间”,我已经直播了多长时间。使用“结束流”按钮,计时器应该停止并重置。我该怎么做?

我尝试了不同的东西,但没有任何想法。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace StreamManagement

    public partial class MainFormProgram : Form
    
        public static bool chat_on = true;
        TimeSpan testTime = DateTime.Now.TimeOfDay;
        public MainFormProgram()
        
            InitializeComponent();
        

        private void chatOnBtn_Click(object sender, EventArgs e)
        
            OnLbl.Text = "ON";
            OnLbl.ForeColor = Color.ForestGreen;
            chatOnBtn.BackColor = Color.LightGray;
            chatOffBtn.BackColor = Color.Gray;
        

        private void chatOffBtn_Click(object sender, EventArgs e)
        
            OnLbl.Text = "OFF";
            OnLbl.ForeColor = Color.DarkRed;
            chatOffBtn.BackColor = Color.LightGray;
            chatOnBtn.BackColor = Color.Gray;
        

        private void Form1_Load(object sender, EventArgs e)
        
            OnLbl.Text = "ON";
            OnLbl.ForeColor = Color.ForestGreen;
            EmoteonlyOnOff.Text = "OFF";
            EmoteonlyOnOff.ForeColor = Color.DarkRed;
            SubchatOnOff.Text = "OFF";
            SubchatOnOff.ForeColor = Color.DarkRed;
        

        private void EmoteOnlyOnBtn_Click(object sender, EventArgs e)
        
            EmoteonlyOnOff.Text = "ON";
            EmoteonlyOnOff.ForeColor = Color.ForestGreen;
            EmoteOnlyOnBtn.BackColor = Color.FromArgb(112, 147, 252);
            EmoteOnlyOffBtn.BackColor = Color.FromArgb(50, 100, 150);
        

        private void EmoteOnlyOffBtn_Click(object sender, EventArgs e)
        
            EmoteonlyOnOff.Text = "OFF";
            EmoteonlyOnOff.ForeColor = Color.DarkRed;
            EmoteOnlyOffBtn.BackColor = Color.FromArgb(112, 147, 252);
            EmoteOnlyOnBtn.BackColor = Color.FromArgb(50, 100, 150);
        

        private void SubChatOnBtn_Click(object sender, EventArgs e)
        
            SubchatOnOff.Text = "ON";
            SubchatOnOff.ForeColor = Color.ForestGreen;
            SubChatOnBtn.BackColor = Color.FromArgb(255, 94, 255);
            SubChatOffBtn.BackColor = Color.FromArgb(192, 0, 192);
        

        private void SubChatOffBtn_Click(object sender, EventArgs e)
        
            SubchatOnOff.Text = "OFF";
            SubchatOnOff.ForeColor = Color.DarkRed;
            SubChatOffBtn.BackColor = Color.FromArgb(255, 94, 255);
            SubChatOnBtn.BackColor = Color.FromArgb(192, 0, 192);
        

        private void startstreamBtn_Click(object sender, EventArgs e)
        
            timerXD.Start();
        

        private void timerXD_Tick(object sender, EventArgs e)
        

        

        private void timerLbl_Click(object sender, EventArgs e)
        

        
    

【问题讨论】:

计时器应打印在标签中 【参考方案1】:

您可以使用 System.Diagnostics 命名空间中的 Stopwatch 类来实现此目的。

在您的 Form 类中创建一个 Stopwatch 字段:

public partial class Form1 : Form

    public Form1()
    
        InitializeComponent();
    

    Stopwatch stopwatch = new Stopwatch(); // <-- this one

创建一个Label(例如lblTime),我们将在您的表单中设置一个向上计数的时间和一个Button,它将以Stopwatch(例如btnStart)开头:

可选您可以添加其他Buttons 以​​使用Stopwatch 进行操作:

Click 处理程序(例如ButtonStart_Click)添加到“开始”按钮以从那里运行秒表。用async 标记它以防止FormStopwatch 运行时冻结:

private async void ButtonStart_Click(object sender, EventArgs e)

    stopwatch.Start();

    while (stopwatch.IsRunning)
    
        lblTime.Text = stopwatch.Elapsed.ToString("hh\\:mm\\:ss");
        await Task.Delay(1000); // Delay between time updates on Form (1 sec)
    

现在你有了“upcount timer”

备注:

    使用stopwatch.Reset(); 停止计时器并重置测量时间。 如果您想停止时间测量,但想保留测量的时间,请使用stopwatch.Stop();。类似于“暂停”。

完成Form代码:

public partial class Form1 : Form

    public Form1()
    
        InitializeComponent();
    

    // "Upcount Timer"
    private readonly Stopwatch stopwatch = new Stopwatch();

    private async void ButtonStart_Click(object sender, EventArgs e)
    
        stopwatch.Start();

        // Disable START button and enable STOP and PAUSE buttons
        btnStart.Enabled = !(btnPause.Enabled = btnStop.Enabled = true);

        while (stopwatch.IsRunning)
        
            // Update time in Label on Form
            lblTime.Text = stopwatch.Elapsed.ToString("hh\\:mm\\:ss");
            // Delay between next update
            await Task.Delay(1000);
        
    
    private void ButtonPause_Click(object sender, EventArgs e)
    
        // Stop timer, but not reset measured time
        stopwatch.Stop();
        // Enable START button and disable STOP and PAUSE buttons
        btnStart.Enabled = !(btnPause.Enabled = btnStop.Enabled = false);
    
    private void ButtonStop_Click(object sender, EventArgs e)
    
        // Stop timer and reset measured time
        stopwatch.Reset();
        
        // Reset time in Label on Form
        lblTime.Text = "00:00:00";
        // or use stopwatch.Elapsed property - after Reset() it would be 00:00:00
        //lblTime.Text = stopwatch.Elapsed.ToString("hh\\:mm\\:ss");
        
        // Enable START button and disable STOP and PAUSE buttons
        btnStart.Enabled = !(btnPause.Enabled = btnStop.Enabled = false);
    

【讨论】:

【参考方案2】:

只需将开始时间存储在 DateTime 中,然后从当前时间中减去该时间即可得到 TimeSpan。使用该 TimeSpan,您可以调用 ToString() 并指定您想要的任何格式。

类似:

DateTime startDT;

private void Form1_Load(object sender, EventArgs e)

    timerXD.Interval = 1000;
    timerXD.Enabled = false;

private void startstreamBtn_Click(object sender, EventArgs e)

    label1.Text = "00:00:00";
    startDT = DateTime.Now;
    timerXD.Start();

private void timerXD_Tick(object sender, EventArgs e)

    String elapsed = DateTime.Now.Subtract(startDT).ToString(@"hh\:mm\:ss");
    label1.Text = elapsed; // display elapsed somehow

【讨论】:

【参考方案3】:

您可以使用一个单独的任务来执行此操作,当您使用 CancellationToken 单击按钮时该任务会取消 在您的班级名称下方,您可以输入以下内容:

public CancellationTokenSource cancellationTokenSource  get; set; 
    public CancellationToken cancellationToken => this.cancellationTokenSource.Token;

您的计时器任务可能如下所示:

private async Task Timer()
    
        CancellationToken cancel = this.cancellationToken;
        int s = 0;


        TimeSpan ts = TimeSpan.FromSeconds(s);
        while(!cancel.IsCancellationRequested)
        
            lbltimer.Text = ts.ToString(@"hh\:mm\:ss");
            await Task.Delay(1000);
            s++;
            ts = TimeSpan.FromSeconds(s);
        
    

现在是按钮

把它放在你的 StartBtn 函数中

cancellationTokenSource = new();
        Timer();

这在你的 StopBtn 函数中

cancellationTokenSource.Cancel();

【讨论】:

如果你想重置计时器,你可以这样做lbltimer.Text = "00:00:00"

以上是关于C# WinForm Upcounter 到 hh:mm:ss的主要内容,如果未能解决你的问题,请参考以下文章

C#将exe运行程序嵌入到自己的winform窗体中

c# 保存图片文件 winform

C# winform鼠标移动到窗口给窗口加边框并获得句柄

我现在用C#做了一个winform程序,如何把整个程序嵌入到网页中运行?急!

c# winform DataGridView添加一行,添加数据后,保存到数据库

C# winform窗体简单保存界面控件参数到xml