Countdown timer with numericupdown - c#

In a Winforms application, there are 3 different numericupdown such as min, sec, millisecond. How do I make a timer that counts down the value of entering numericupdowns? I have tried with if else blocks. I also saw a lot of time timespawn titles on the internet. Which is better for this countdown? if else blocks or timespawn
numericUpDownMiliSn.Value--;
if (numericUpDownMiliSn.Value == 0)
{
if (numericUpDownMiliSn.Value == 0 && numericUpDownSn.Value == 0 && numericUpDownDk.Value == 0)
{
timer2.Stop();
button2.Text = "Baslat";
durum = false;
}
else
{
if (numericUpDownSn.Value > 0)
{
numericUpDownSn.Value--;
numericUpDownMiliSn.Value = 60;
}
else
{
numericUpDownMiliSn.Value = 60;
}
if (numericUpDownSn.Value > 0)
{
numericUpDownSn.Value--;
numericUpDownSn.Value = 60;
}
}
}

From my comments in the original question above:
Timers in WinForms are NOT accurate, so you shouldn't be basing your
time off incrementing/decrementing those in a Tick() event. You should
definitely be using a TimeSpan (derived from subtracting the current
time from some future target time; based on the initial values in your
NumericUpDowns)...then simply update the NumericUpDowns with the
numbers in the TimeSpan.
Here's how that code might look:
private DateTime targetDT;
private void button1_Click(object sender, EventArgs e)
{
TimeSpan ts = new TimeSpan(0, 0, (int)numericUpDownMn.Value, (int)numericUpDownSn.Value, (int)numericUpDownMiliSn.Value);
if (ts.TotalMilliseconds > 0)
{
button1.Enabled = false;
numericUpDownMn.Enabled = false;
numericUpDownSn.Enabled = false;
numericUpDownMiliSn.Enabled = false;
targetDT = DateTime.Now.Add(ts);
timer1.Start();
}
}
private void timer1_Tick(object sender, EventArgs e)
{
TimeSpan ts = targetDT.Subtract(DateTime.Now);
if (ts.TotalMilliseconds > 0)
{
numericUpDownMn.Value = ts.Minutes;
numericUpDownSn.Value = ts.Seconds;
numericUpDownMiliSn.Value = ts.Milliseconds;
}
else
{
timer1.Stop();
numericUpDownMn.Value = 0;
numericUpDownSn.Value = 0;
numericUpDownMiliSn.Value = 0;
button1.Enabled = true;
numericUpDownMn.Enabled = true;
numericUpDownSn.Enabled = true;
numericUpDownMiliSn.Enabled = true;
}
}

Related

Why when changing the seconds trackBar down to the left and then start the timer it's starting from higher second/s?

For example, if I set the trackBar of the hours to 3, the trackBar of the minutes to 5, and the bottom trackBar of the seconds to 6 then clicking the start button it will count down fine starting from the 6 seconds.
But then I click the stop button changing the trackBar of the seconds only from 6 to 3 then click the start button, it will count down but from the 6 second and not the 3. I changed the trackBar value of the seconds to 3 but it's starting from 6. Not sure why.
public partial class Form1 : Form
{
private static readonly Stopwatch watch = new Stopwatch();
private long diff = 0, previousTicks = 0, ticksDisplayed = 0;
public Form1()
{
InitializeComponent();
richTextBox1.TabStop = false;
richTextBox1.ReadOnly = true;
richTextBox1.BackColor = Color.White;
richTextBox1.Cursor = Cursors.Arrow;
richTextBox1.Enter += RichTextBox1_Enter; ;
UpdateTime();
}
private void RichTextBox1_Enter(object sender, EventArgs e)
{
btnStart.Focus();
}
private void UpdateTime()
{
richTextBox1.Text = GetTimeString(watch.Elapsed);
}
private string GetTimeString(TimeSpan elapsed)
{
string result = string.Empty;
//calculate difference in ticks
diff = elapsed.Ticks - previousTicks;
if (radioButton1.Checked == true)
{ //counting up
ticksDisplayed += diff;
}
else
{ //counting down
ticksDisplayed -= diff;
}
if (ticksDisplayed < 0)
{
ticksDisplayed = 0;
}
//Make ticksDisplayed to regular time to display in richtextbox
TimeSpan ctimeSpan = new TimeSpan(ticksDisplayed);
result = string.Format("{0:00}:{1:00}:{2:00}.{3:000}",
ctimeSpan.Hours,
ctimeSpan.Minutes,
ctimeSpan.Seconds,
ctimeSpan.Milliseconds);
previousTicks = elapsed.Ticks;
return result;
}
private void btnStart_Click(object sender, EventArgs e)
{
if (btnStart.Text == "START")
{
watch.Reset();
watch.Start();
UpdateTime();
btnStart.Text = "STOP";
timer1.Enabled = true;
}
else
{
watch.Stop();
btnStart.Text = "START";
btnPause.Text = "PAUSE";
timer1.Enabled = false;
}
}
private void btnReset_Click(object sender, EventArgs e)
{
watch.Reset();
diff = 0;
previousTicks = 0;
ticksDisplayed = 0;
trackBarHours.Value = 0;
trackBarMinutes.Value = 0;
trackBarSeconds.Value = 0;
UpdateTime();
}
private void trackBarHours_Scroll(object sender, EventArgs e)
{
//get ticksDisplayed as TimeSpan
TimeSpan ctimeSpan = new TimeSpan(ticksDisplayed);
//change only the hour
TimeSpan htimeSpan = new TimeSpan(ctimeSpan.Days, trackBarHours.Value, ctimeSpan.Minutes, ctimeSpan.Seconds, ctimeSpan.Milliseconds);
//set it to ticksDisplayed and update.
ticksDisplayed = htimeSpan.Ticks;
UpdateTime();
}
private void trackBarMinutes_Scroll(object sender, EventArgs e)
{
TimeSpan ctimeSpan = new TimeSpan(ticksDisplayed);
TimeSpan mtimeSpan = new TimeSpan(ctimeSpan.Days, ctimeSpan.Hours, trackBarMinutes.Value, ctimeSpan.Seconds, ctimeSpan.Milliseconds);
ticksDisplayed = mtimeSpan.Ticks;
UpdateTime();
}
private void trackBarSeconds_Scroll(object sender, EventArgs e)
{
TimeSpan ctimeSpan = new TimeSpan(ticksDisplayed);
TimeSpan stimeSpan = new TimeSpan(ctimeSpan.Days, ctimeSpan.Hours, ctimeSpan.Minutes, trackBarSeconds.Value, ctimeSpan.Milliseconds);
ticksDisplayed = stimeSpan.Ticks;
UpdateTime();
}
private void btnPause_Click(object sender, EventArgs e)
{
if (btnStart.Text == "STOP")
{
if (btnPause.Text == "PAUSE")
{
btnPause.Text = "CONTINUE";
watch.Stop();
timer1.Enabled = false;
}
else
{
btnPause.Text = "PAUSE";
watch.Start();
timer1.Enabled = true;
}
}
}
private void timer1_Tick(object sender, EventArgs e)
{
UpdateTime();
}
}
As far for now, I checked it only with the seconds trackBar when changing to 6, for example, seconds then start then stop then changing it to 3 then start again it will start from 6 and not from 3.
It is because when you reset the Stopwatch you didn't set time to trackbar values:
if( button1.Text == "START" ) {
watch.Reset();
//Here
TimeSpan ctimeSpan = new TimeSpan( 0, trackBar1.Value, trackBar2.Value, trackBar3.Value, 0 );
diff = 0;
previousTicks = 0;
ticksDisplayed = ctimeSpan.Ticks;
watch.Start();
button1.Text = "STOP";
timer1.Enabled = true;
}
else {
watch.Stop();
button1.Text = "START";
button2.Text = "PAUSE";
timer1.Enabled = false;
}

C#: 2 Timer objects not working?

I'm trying to make a simple countdown timer program. There are two timer objects. Once timer1 runs out of time, it stops and timer2 starts counting down. When timer2 runs out of time, timer1 starts again and so on. Here is my code:
private void timer1_Tick(object sender, EventArgs e)
{
milli1--;
if(milli1 == -1)
{
sec1--;
milli1 = 59;
if (sec1 == -1)
{
min1--;
sec1 = 59;
if (min1 == -1)
{
min1 = 0;
sec1 = 0;
milli1 = 0;
Console.WriteLine("Timer1 stops!");
timer1.Stop();
timer2.Start();
}
}
}
//updates displayed time
}
However, when timer1 stops, timer2 doesn't seem to start. Somehow, timer1 continues ticking and continuously outputs "Timer1 Stops!" to console. How do I fix this?
EDIT: Here is my timer2_Tick():
private void timer2_Tick(object sender, EventArgs e)
{
milli2--;
if (milli2 == -1)
{
sec2--;
milli2 = 59;
if (sec2 == -1)
{
min2--;
sec2 = 59;
if (min2 == -1)
{
min2 = 0;
sec2 = 0;
milli2 = 0;
timer2.Stop();
timer1.Start();
}
}
}
//updates displayed time
}
EDIT 2: Two timers with same interval is a trivial matter. My code also doesn't work when the timers have different intervals.
I am not sure why you want to use a Timer for a console application as it is not event driven as a Windows.Forms.Timer is. You may be using a Threading timer but your code won’t work as it is using this timer. So below I created a windows form application and set the output type to the console and used the timers as you described and it works as expected. I do not think you can use a timer the way you are in a console application. Again this code makes little sense as ONE timer will do the same thing. If you must use a console application then you may want to check the following post: How do you add a timer to a C# console application
int milli1 = 0;
int milli2 = 0;
int sec1 = 0;
int min1 = 0;
int sec2 = 0;
int min2 = 0;
public Form1() {
InitializeComponent();
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e) {
Console.WriteLine("Timer1 tick!");
milli1--;
if (milli1 == -1) {
sec1--;
milli1 = 59;
if (sec1 == -1) {
min1--;
sec1 = 59;
if (min1 == -1) {
min1 = 0;
sec1 = 0;
milli1 = 0;
//Console.WriteLine("Timer1 stops!");
timer1.Stop();
timer2.Start();
}
}
}
//updates displayed time
}
private void timer2_Tick(object sender, EventArgs e) {
Console.WriteLine("Timer2 tick!");
milli2--;
if (milli2 == -1) {
sec2--;
milli2 = 59;
if (sec2 == -1) {
min2--;
sec2 = 59;
if (min2 == -1) {
min2 = 0;
sec2 = 0;
milli2 = 0;
timer2.Stop();
timer1.Start();
}
}
}
//updates displayed time
}
}

How can i make that if i click the button the timer will count up instead down?

How can i make that if i click on the button the flag will be true and in the timer1 tick event it will change the count and will count up. And if i click the same button again it will count down. Without resetting the timer just to keep from the point it was to count up or down depending on the flag. If True it should count up, if false it should count down. ( The flag is set to false in the top of the form ).
Now the way it is it's counting only back (down).
This the timer1 tick event:
private void timer1_Tick(object sender, EventArgs e)
{
if (hours == 0 && mins == 0 && secs == 0)
{
timer1.Stop();
MessageBox.Show(new Form() { TopMost = true }, "Times up!!! :P", "Will you press OK? :P", MessageBoxButtons.OK, MessageBoxIcon.Information);
textBox1.Text = "00";
textBox2.Text = "00";
textBox3.Text = "00";
textBox3.Enabled = true;
textBox2.Enabled = true;
textBox1.Enabled = true;
button1.Enabled = true;
lblHr.Text = "00";
lblMin.Text = "00";
lblSec.Text = "00";
button2.Enabled = false;
button3.Enabled = false;
}
else
{
if (secs < 1)
{
secs = 59;
if (mins < 1)
{
mins = 59;
if (hours != 0)0
hours -= 1;
}
else mins -= 1;
}
else secs -= 1;
if (hours > 9)
lblHr.Text = hours.ToString();
else lblHr.Text = "0" + hours.ToString();
if (mins > 9)
lblMin.Text = mins.ToString();
else lblMin.Text = "0" + mins.ToString();
if (secs > 9)
lblSec.Text = secs.ToString();
else lblSec.Text = "0" + secs.ToString();
}
}
private void button4_Click(object sender, EventArgs e)
{
count_up_down = true;
}
First, change the representation of time from hours, minutes, and seconds to plain seconds. Set the text in labels by dividing seconds by 60 and 3600, like this:
int hours = totalSeconds / 3600;
int minutes = totalSeconds / 60;
int seconds = totalSeconds % 60;
Add an integer instance variable called step, and set it to negative 1:
private int step = -1;
On button click, change the sign of the step variable:
step = -step;
Now all you need to do is to change the code to use totalSeconds += step instead of xyz -= 1 - and you are done!
DateTime start = DateTime.MinValue;
TimeSpan oldTime = TimeSpan.Parse("00:00:00");
tm = new Timer();
tm.Tick += new EventHandler(tm_Tick);
void tm_Tick(object sender, EventArgs e)
{
TimeSpan runTime = DateTime.Now - start;
lblTimer.Text = string.Format("{1:D2}:{2:D2}:{3:D2}",
runTime.Days,
runTime.Hours,
runTime.Minutes,
runTime.Seconds);
}
Hope the above code will help you.

CountDown check Time

I've made an countdown and i want to add an time check for it now. If the minutes are < 01 and the seconds are != 60 so 00:59 the Time should be orange and if the seconds are then smaller then 10 the time should be red.
But it does not work.
They're always just getting orange if the time is 00:00:58, but why?
private int hours, minutes, seconds;
private bool paused;
private void button_Start_Click(object sender, EventArgs e)
{
button_Pause.Enabled = true;
button_Stop.Enabled = true;
if(paused != true)
{
hours = int.Parse(textBox_Hours.Text);
minutes = int.Parse(textBox_Minutes.Text);
seconds = int.Parse(textBox_Seconds.Text) + 1;
textBox_Hours.Enabled = false;
textBox_Minutes.Enabled = false;
textBox_Seconds.Enabled = false;
button_Start.Enabled = false;
timer_CountDown.Start();
}
}
private void timer_CountDown_Tick(object sender, EventArgs e)
{
if(hours == 0 && minutes < 1)
{
label_Hours.ForeColor = Color.Red;
label_Minutes.ForeColor = Color.Red;
label_Seconds.ForeColor = Color.Red;
label8.ForeColor = Color.Red;
label10.ForeColor = Color.Red;
}
if(hours == 0 && minutes == 0 && seconds == 0)
{
timer_CountDown.Stop();
textBox_Seconds.Enabled = true;
textBox_Minutes.Enabled = true;
textBox_Hours.Enabled = true;
button_Start.Enabled = true;
}
else
{
if (seconds < 1)
{
seconds = 59;
if (minutes < 1)
{
minutes = 59;
if (hours != 0)
{
hours -= 1;
}
}
else
{
minutes -= 1;
}
}
else
{
seconds -= 1;
}
if(hours > 9)
{
label_Hours.Text = hours.ToString();
}
else { label_Hours.Text = "0" + hours.ToString(); }
if(minutes > 9)
{
label_Minutes.Text = minutes.ToString();
}
else { label_Minutes.Text = "0" + minutes.ToString(); }
if(seconds > 9)
{
label_Seconds.Text = seconds.ToString();
}
else { label_Seconds.Text = "0" + seconds.ToString(); }
}
}
The Timer Intervall is 1000.
You're over complicating things. Why not just use the TimeSpan type and get rid of those hours, minutes, seconds?
private TimeSpan countDownTime = TimeSpan.Zero;
private void timer_CountDown_Tick(object sender, EventArgs e)
{
if(countDownTime == TimeSpan.Zero)
{
timer_CountDown.Stop();
textBox_Seconds.Enabled = true;
textBox_Minutes.Enabled = true;
textBox_Hours.Enabled = true;
button_Start.Enabled = true;
return;
}
countDownTime = countDownTime.Add(TimeSpan.FromSeconds(1).Negate());
label_Hours.Text = countDownTime.ToString("hh");
label_Minutes.Text = countDownTime.ToString("mm");
label_Seconds.Text = countDownTime.ToString("ss");
if(countDownTime.TotalSeconds < 10)
{
label_Hours.ForeColor = Color.Red;
label_Minutes.ForeColor = Color.Red;
label_Seconds.ForeColor = Color.Red;
label8.ForeColor = Color.Red;
label10.ForeColor = Color.Red;
}
else if (countDownTime.TotalMinutes < 1)
{
label_Hours.ForeColor = Color.Orange;
label_Minutes.ForeColor = Color.Orange;
label_Seconds.ForeColor = Color.Orange;
label8.ForeColor = Color.Orange;
label10.ForeColor = Color.Orange;
}
}
private void button_Start_Click(object sender, EventArgs e)
{
button_Pause.Enabled = true;
button_Stop.Enabled = true;
if(paused != true)
{
int hours = int.Parse(textBox_Hours.Text);
int minutes = int.Parse(textBox_Minutes.Text);
int seconds = int.Parse(textBox_Seconds.Text) + 1;
this.countDownTime = new TimeSpan(hours,minutes,seconds);
textBox_Hours.Enabled = false;
textBox_Minutes.Enabled = false;
textBox_Seconds.Enabled = false;
button_Start.Enabled = false;
timer_CountDown.Start();
}
}

Displaying two labels for one second through a timer

I'm making a little game in C#
When the score is 100, I want two labels to display for one second, then they need to be invisible again.
At the moment I have in Form1:
void startTimer(){
if (snakeScoreLabel.Text == "100"){
timerWIN.Start();
}
}
private void timerWIN_Tick(object sender, EventArgs e)
{
int timerTick = 1;
if (timerTick == 1)
{
lblWin1.Visible=true;
lblWin2.Visible=true;
}
else if (timerTick == 10)
{
lblWin1.Visible = false;
lblWin2.Visible = false;
timerWIN.Stop();
}
timerTick++;
}
The timer's interval is 1000ms.
Problem = labels aren't showing at all
Timers are pretty new to me, so I'm stuck here :/
Try this :
void startTimer()
{
if (snakeScoreLabel.Text == "100")
{
System.Timers.Timer timer = new System.Timers.Timer(1000) { Enabled = true };
timer.Elapsed += (sender, args) =>
{
lblWin1.Visible=true;
timer.Dispose();
};
}
}
Try multithreaded System.Threading.Timer :
public int TimerTick = 0;
private System.Threading.Timer _timer;
public void StartTimer()
{
label1.Visible = true;
label2.Visible = true;
_timer = new System.Threading.Timer(x =>
{
if (TimerTick == 10)
{
Invoke((Action) (() =>
{
label1.Visible = false;
label2.Visible = false;
}));
_timer.Dispose();
TimerTick = 0;
}
else
{
TimerTick++;
}
}, null, 0, 1000);
}

Categories