Reputation: 71
I have a timer set up, but can't work out how to add time by using buttons to add 10 seconds, 1 minute and 10 minutes respectively. I'm not sure if I've managed to get it to count down correctly, as I copied code from a timer that counted up and tried to reverse it. Any help would be much appreciated. Here's my code:
int Ten_Sec = 10000;
int One_Min = 60000;
int Ten_Min = 600000;
System.Timers.Timer t ;
int hour, min, sec;
private void Form1_Load(object sender, EventArgs e)
{
t = new System.Timers.Timer();
t.Interval = 1000; //1sec
t.Elapsed -= OnTimeEvent;
}
private void Button_Ten_Sec_Click_1(object sender, EventArgs e)
{
Ten_Sec++;
}
private void Button_One_Min_Click_1(object sender, EventArgs e)
{
One_Min++;
}
private void Button_Ten_Min_Click_1(object sender, EventArgs e)
{
Ten_Min++;
}
private void OnTimeEvent(object sender, ElapsedEventArgs e)
{
Invoke (new Action(() =>
{
sec -= 1;
if (sec == 60)
{
sec = 0;
min -= 1;
}
if (min == 60)
{
min = 0;
hour -= 1;
}
textBox_Timer.Text = String.Format("{0},{1},{2}", hour.ToString().PadLeft(2, '0'), min.ToString().PadLeft(2, '0'), sec.ToString().PadLeft(2, '0'));
}));
}
Upvotes: 2
Views: 5825
Reputation: 37020
There are a few basic things to know about at timer:
Tick
event (or an Elapsed
event, depending on the timer you're using). It raises this event on a regular basis. You can subscribe one or more methods to this event, and they will be triggered at regular intervalsInterval
- this is the nubmer of milliseconds it waits before raising the Tick
event.Enabled
property. If this is set to false, the timer is not running.Start
method. Call this method to start the timer. It also has a Stop
method that you can call when you want it to stop. These methods also set the Enabled
property, so if you call Stop
, then Enabled
will be set to false
.Looking at your code from top down, the first thing I would do is get rid of these variables. They aren't doing anything, and the TimeSpan
class already has an easy way to specify a number of minutes or seconds:
// We don't need these
int Ten_Sec = 10000;
int One_Min = 60000;
int Ten_Min = 600000;
Also, you are using a System.Timers.Timer
, which may cause some troubles when trying to update the control text, since it runs in another thread. Instead, let's use a System.Windows.Forms.Timer
:
public partial class Form1 : Form
{
System.Windows.Forms.Timer timer;
We could also use a variable to hold the time that we're displaying. If we make this a class-level variable, then we can change it both from the timer's Tick
event as well as from buttons that the user clicks:
public partial class Form1 : Form
{
System.Windows.Forms.Timer timer;
TimeSpan countdownClock = TimeSpan.Zero;
Now, in your Form_Load
, you're doing the right things, except you are un-subscribing the OnTimeEvent
from the timer. If anything, we should be subscribing to the event instead, so we have some code to execute when the timer elapses.
Also notice I renamed your timer from t
to timer
. It increases readability and doesn't really slow down coding since Visual Studio gives intellisense as soon as you type t
. And I used the TimeSpan.FromSeconds
method to set the timer interval, which makes it more obvious what the interval is:
private void Form1_Load(object sender, EventArgs e)
{
timer = new System.Windows.Forms.Timer();
timer.Interval = (int) TimeSpan.FromSeconds(1).TotalMilliseconds;
timer.Tick += OnTimeEvent;
DisplayTime();
}
You might be wondering what DisplayTime()
is there for. I wrote a small function to display the time on the form, since we're doing it from more than one place and it has a specific format string. Now that this is done in one place, if you want to change the format, there's only one place to change the code.
Also, I noticed that you were using a TextBox
to display the time, but for a read-only value, it's probably better to use a Label
. I created one named lblTime
:
private void DisplayTime()
{
lblTime.Text = countdownClock.ToString(@"hh\:mm\:ss");
}
Now, in answer to one of your main questions: How do we stop the timer when it gets to 0
? We can do this in the OnTimeEvent
event, since this is the moment when the timer is reading the current countdown clock and removing a second from it.
Notice that the signature of this method is slightly different than yours. Since I'm using a different type of timer, the requirements are different:
private void OnTimeEvent(object sender, EventArgs e)
{
// Subtract whatever our interval is from the countdownClock
countdownClock = countdownClock.Subtract(TimeSpan.FromMilliseconds(timer.Interval));
if (countdownClock.TotalMilliseconds <= 0)
{
// Countdown clock has run out, so set it to zero
// (in case it's negative), and stop our timer
countdownClock = TimeSpan.Zero;
timer.Stop();
}
// Display the current time
DisplayTime();
}
So the only thing left to do is enable the timer. Since we're starting at 0
, there is no where to count down to, but you appear to have some buttons on your form for adding time to the clock, so let's use those.
Because we'll be updating the time from multiple places, and this also requires a check to see if the timer is disabled and to start it if it isn't, I created a helper method to add time to the clock:
private void AddTimeToClock(TimeSpan timeToAdd)
{
// Add time to our clock
countdownClock += timeToAdd;
// Display the new time
DisplayTime();
// Start the timer if it's stopped
if (!timer.Enabled) timer.Start();
}
Now, in each button we'll just call that function, passing a different span of time depending on which button was pressed:
private void Button_Ten_Sec_Click(object sender, EventArgs e)
{
// Add ten seconds to our clock
AddTimeToClock(TimeSpan.FromSeconds(10));
}
private void Button_One_Min_Click(object sender, EventArgs e)
{
// Add one minute to our clock
AddTimeToClock(TimeSpan.FromMinutes(1));
}
private void Button_Ten_Min_Click(object sender, EventArgs e)
{
// Add ten minutes to our clock
AddTimeToClock(TimeSpan.FromMinutes(10));
}
Hopefully that's enough to get you going. You now have a countdown timer that will stop when it gets to 0
, and which you can add time to from your buttons.
Upvotes: 3
Reputation: 697
I would take a look at the DateTime and the TimeSpan structure. You can manipulate them to output whatever amount of time you want as well as adding and subtracting time from it. Given your example, you may want to use TimeSpan
TimeSpan testTime = DateTime.Now.TimeOfDay;
public Form1()
{
InitializeComponent();
timer1.Enabled = true;
timer1.Interval = 1000;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
testTime = testTime.Subtract(new TimeSpan(0, 0, 1));
lblTime.Text = testTime.ToString("hh\\:mm\\:ss");
}
private void button1_Click(object sender, EventArgs e)
{
testTime = testTime.Add(new TimeSpan(1, 0, 0));
lblTime.Text = testTime.ToString("hh\\:mm\\:ss");
}
private void button2_Click(object sender, EventArgs e)
{
testTime = testTime.Add(new TimeSpan(0, 1, 0));
lblTime.Text = testTime.ToString("hh\\:mm\\:ss");
}
private void button3_Click(object sender, EventArgs e)
{
testTime = testTime.Add(new TimeSpan(0, 0, 1));
lblTime.Text = testTime.ToString("hh\\:mm\\:ss");
}
which results in the following:
Upvotes: 1