I want to Write a Program like OBS Studio and i wanna add an Upcounter to my Program so that means when i click "Start Stream" it should start the Upcounter from 00:00:00 to 00:00:01 then to 00:00:02 and so on so that i have the "Livetime", how long i am already streaming. And with the "End Stream" Button the Timer should Stop and Reset. How can i do that?
i tried different things but dont had an idea.
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)
{
}
}
}
CodePudding user response:
Just store the start time in a DateTime and then subtract that from the current time to get a TimeSpan. With that TimeSpan you can call ToString() and specify whatever format you want.
Something like:
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
}
CodePudding user response:
You can use Stopwatch
class from System.Diagnostics
namespace for that purpose.
Create a Stopwatch
field in your Form
class:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Stopwatch stopwatch = new Stopwatch(); // <-- this one
}
Create a Label
(lblTime
for example), to which we would set upcounted time and a Button
at your Form, which would start Stopwatch
(btnStart
for example):
Optionally you may add other Button
s to manipulate with Stopwatch
:
Add Click
handler (ButtonStart_Click
for example) to "START" button to run Stopwatch from there. Mark it with async
to prevent Form
freezes while Stopwatch
running:
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)
}
}
Now you have "upcount timer".
Remarks:
- Use
stopwatch.Reset();
to stop timer and reset measured time. - Use
stopwatch.Stop();
if you want to stop time measurement, but want to keep meaused time. Similar to "Pause".
Complete Form
code:
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);
}
}
CodePudding user response:
You can do this with a seperate Task that cancels when you click the button using a CancellationToken Right below your class name you can put this:
public CancellationTokenSource cancellationTokenSource { get; set; }
public CancellationToken cancellationToken => this.cancellationTokenSource.Token;
Your timer Task can look something like this:
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);
}
}
Now for the Buttons
Put this in your StartBtn Function
cancellationTokenSource = new();
Timer();
and this in your StopBtn Function
cancellationTokenSource.Cancel();