Reputation: 3
I'm trying to create a countdown timer with user input. Below is the code that just starts a timer of 5 minutes then ends. I want to use something like a Numericupdown to add multiples of 5 minutes, if it is 1 then it's 5 mins, 2 it countsdown from 10 mins etc. I will probably use a second button (button2) to set the time (read from numericupdown, add the minutes then show it on label1) before pressing button1 to start the countdown.
I can't figure out a way of doing it. Do I need to use a For loop?
Dim TimerEnds As DateTime
Dim TimerRunning As Boolean
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Button1.Text = "Start" Then
TimerRunning = True
TimerEnds = DateTime.Now.AddMinutes(5)
Button1.Text = "Stop"
Else
TimerRunning = False
Button1.Text = "Start"
Label1.Text = "00:05:00"
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Dim howLong As TimeSpan = TimerEnds - DateTime.Now
If TimerRunning Then
If howLong.TotalMilliseconds > 0 Then
Label1.Text = howLong.ToString("hh\:mm\:ss")
Else
Label1.Text = "Finished"
TimerRunning = False
End If
End If
End Sub
Upvotes: 0
Views: 228
Reputation: 54417
Here's a class that you can use instead of a standard Timer
that will remove the need for most of your code:
Public Class CountdownTimer
Inherits System.Windows.Forms.Timer
''' <summary>
''' Measures elapsed time.
''' </summary>
Private ReadOnly stopwatch As New Stopwatch
''' <summary>
''' Indicates whether the <see cref="Expired"/> event has been raised.
''' </summary>
Private expiredRaised As Boolean = False
''' <summary>
''' Gets or sets the amount of time to count down.
''' </summary>
Public Property Period As TimeSpan
''' <summary>
''' Gets the amount of time until expiration.
''' </summary>
Public ReadOnly Property Remaining As TimeSpan
Get
Return If(stopwatch.Elapsed < Period,
Period - stopwatch.Elapsed,
TimeSpan.Zero)
End Get
End Property
''' <summary>
''' Gets a value indicating whether the time period has expired.
''' </summary>
Public ReadOnly Property HasExpired As Boolean
Get
Return Remaining = TimeSpan.Zero
End Get
End Property
''' <summary>
''' Gets a value indicating whether the timer should stop raising <see cref="Tick"/> events when the period expires.
''' </summary>
''' <returns></returns>
Public Property StopOnExpiration As Boolean = True
''' <summary>
''' Occurs when the period has expired.
''' </summary>
Public Event Expired As EventHandler
''' <summary>
''' Starts the timer.
''' </summary>
Public Shadows Sub Start()
MyBase.Start()
stopwatch.Start()
End Sub
''' <summary>
''' Stops the timer.
''' </summary>
Public Shadows Sub [Stop]()
MyBase.Stop()
stopwatch.Stop()
End Sub
''' <summary>
''' Resets the timer.
''' </summary>
Public Sub Reset()
stopwatch.Reset()
expiredRaised = False
End Sub
''' <summary>
''' Raises the <see cref="Tick"/> event.
''' </summary>
Protected Overrides Sub OnTick(e As EventArgs)
'Stop the timer when the period has expired, if configured to do so.
If HasExpired AndAlso StopOnExpiration Then
[Stop]()
End If
MyBase.OnTick(e)
'Raise the Expired event once when the period expires.
If HasExpired AndAlso Not expiredRaised Then
OnExpired(EventArgs.Empty)
End If
End Sub
''' <summary>
''' Raises the <see cref="Expired"/> event.
''' </summary>
Protected Overridable Sub OnExpired(e As EventArgs)
'Ensure the Expired event is only raised once, even if the Tick event continues to be raised.
expiredRaised = True
RaiseEvent Expired(Me, e)
End Sub
End Class
You could then use it like this:
Private Sub DisplayTimeRemaining()
Label1.Text = CountdownTimer1.Remaining.ToString("hh\:mm\:ss")
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If CountdownTimer1.Enabled Then
CountdownTimer1.Stop()
CountdownTimer1.Reset()
Button1.Text = "Start"
Else
Button1.Text = "Stop"
CountdownTimer1.Reset()
CountdownTimer1.Period = TimeSpan.FromMinutes(NumericUpDown1.Value * 5)
CountdownTimer1.Start()
End If
DisplayTimeRemaining()
End Sub
Private Sub CountdownTimer1_Tick(sender As Object, e As EventArgs) Handles CountdownTimer1.Tick
DisplayTimeRemaining()
End Sub
Private Sub CountdownTimer1_Expired(sender As Object, e As EventArgs) Handles CountdownTimer1.Expired
Label1.Text = "Finished"
Button1.Text = "Start"
End Sub
Upvotes: 1