I've been struggling with this for the last few days and am hoping that you all can help me out. I'm creating a WPF timer application and am using DispatcherTimer in order to count upwards in minutes to track time. When I start the timer initally, it works perfectly. However, when I stop the timer, then start it back up, it begins to count by 2's. If I do it again, it counts by 3's, and so on. I'm not entirely sure about what all can be done with DispatcherTimer, so that's where I could really use some help.
This is the initial function that gets called when the Start Button is clicked.
private void TimerStart(object sender, RoutedEventArgs e)
{
if ((string) TimerBlock.Content == "--:--")
{
TimerBlock.Content = "00:00";
TimerTray.Content = "00:00";
}
else
{
var timerString = TimerBlock.Content.ToString();
_minute = Convert.ToInt32(timerString.Substring(0, 2));
_hour = Convert.ToInt32(timerString.Substring(3, 2));
}
_timer.Interval = TimerBlock.Content.ToString();
_timer.Tick += dispatcherTimer_tick;
_timer.Start();
TaskBarStop.IsChecked = false;
TimerStatus.Content = "The Timer Has Started";
TimerStatus.Foreground = System.Windows.Media.Brushes.DarkGreen;
TimerTrayStatus.Content = "STARTED";
TimerTrayStatus.Foreground = System.Windows.Media.Brushes.DarkGreen;
StartButton.IsEnabled = false;
StopButton.IsEnabled = true;
}
Here is the tick.
private void dispatcherTimer_tick(object sender, EventArgs e)
{
if (_minute++ == 60)
{
_minute = 0;
_hour++;
}
if (_hour < 10 && _minute < 10)
TimerBlock.Content = "0" + _hour + ":0" + _minute;
else if (_hour < 10 && _minute >= 10)
TimerBlock.Content = "0" + _hour + ":" + _minute;
else if (_hour >= 10 && _minute < 10)
TimerBlock.Content = _hour + ":0" + _minute;
else
TimerBlock.Content = _hour + ":" + _minute;
TimerTray.Content = TimerBlock.Content;
CommandManagaer.InvalidateRequerySuggested();
}
And here is the method called when the stop button is pressed.
private void TimerStop(object sender, RoutedEventArgs e)
{
_timer.Stop();
TaskBarStart.IsChecked = false;
TimerStatus.Content = "The Timer Has Stopped";
TimerStatus.Foreground = System.Windows.Media.Brushes.DarkRed;
TimerTrayStatus.Content = "STOPPED";
TimerTrayStatus.Foreground = System.Windows.Media.Brushes.DarkRed;
StartButton.IsEnabled = true;
StopButton.IsEnabled = false;
using (var db = new TimerDb())
{
var timer = TimerBlock.Content.ToString();
var session = new TimerSession();
if (db.TemporaryTimeActivities.Any())
session.SetTimeActivity(timer);
else
session.UpdateTime(timer);
}
}
Basically, I can't figure out if it's just something small that I'm overlooking, or if I've messed up something pretty bad somewhere else. Any help would be greatly appreciated. Is there something that I've put in the code that causes it to increase the interval by 1 each time it's restarted?
You should attach the Tick handler only once, not each time you start the timer.
So move the line
out of the
TimerStart
method and put it e.g. in the Window's or UserControl's constructor.Also you should make sure that the timer's
Interval
is set correctly. It looks like you want to get the Tick handler called once every minute, so you should set it accordingly:It would also be easier (and more accurate) not to count the minutes yourself, but instead use the
DateTime
andTimeSpan
structs. Use theDateTime.Now
property to store the start time in a field of type DateTime in the TimerStart method.and take advantage of the string formatting features of the TimeSpan class: