I have a countdown timer in my application that is to be controlled via keyboard. Currently, it will start (or reset to the starting value of 20minutes) when the user presses "B", and stop when the user presses "A". Trying to figure out how to restart the timer from the stopped time. i.e. if the user presses "A" at timer 15 mins 32 seconds, pressing a again would resume the countdown. Here is the code I have currently (at least as it pertains to the countdown).

PrivateSub Me_KeyDown(ByVal sender AsObject, ByVal e As System.Windows.Forms.KeyEventArgs) HandlesMe.KeyDown
If e.KeyCode = Keys.B Then
Timer1.Enabled = True
CountDownStart = Microsoft.VisualBasic.DateAndTime.Timer
ElseIf e.KeyCode = Keys.A Then
Timer1.Enabled = False
End If
End Sub

Would someone be kind enough to point me in the right direction please?

Dani AI

Generated

The observed jump on resume is caused by measuring elapsed time from a fixed system timestamp rather than tracking the remaining time while paused. ’s use of an absolute start time (CountDownStart) means the system clock keeps advancing when the UI is paused; ’s toggle stops the UI updates but does not change that calculation; ’s idea of storing a countdown variable is the simplest workable pattern for one-second granularity. A more robust pattern avoids relying on system clock differences and handles multiple pause/resume cycles cleanly.

Two reliable options:

  • Keep a single "remaining" value (seconds or TimeSpan) and decrement it inside the timer tick. Simple and effective for a 1s interval.
  • Use a Stopwatch to measure only active run time and maintain an accumulated elapsed TimeSpan for paused periods. This is more accurate if the app can be delayed by CPU load or needs sub-second accuracy.

Example (Stopwatch + accumulated elapsed):

Private ReadOnly TotalDuration As TimeSpan = TimeSpan.FromMinutes(20)
Private savedElapsed As TimeSpan = TimeSpan.Zero
Private sw As New System.Diagnostics.Stopwatch()

Private Sub Form_Load(...) Handles MyBase.Load
    Timer1.Interval = 1000
    Timer1.Enabled = False
    Me.KeyPreview = True
End Sub

Private Sub Form_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
    If e.KeyCode = Keys.B Then
        savedElapsed = TimeSpan.Zero
        sw.Restart()
        Timer1.Enabled = True
    ElseIf e.KeyCode = Keys.A Then
        If sw.IsRunning Then
            sw.Stop()
            savedElapsed += sw.Elapsed
        Else
            sw.Restart()
        End If
    End If
End Sub

Private Sub Timer1_Tick(...) Handles Timer1.Tick
    Dim elapsed = savedElapsed + If(sw.IsRunning, sw.Elapsed, TimeSpan.Zero)
    Dim remaining = TotalDuration - elapsed
    If remaining <= TimeSpan.Zero Then
        Timer1.Enabled = False
        sw.Stop()
        Label1.Text = "00:00"
    Else
        Label1.Text = remaining.ToString("mm\:ss")
    End If
End Sub

Notes: enable Form.KeyPreview to catch keys at form level and use KeyUp (or swallow repeats with e.Handled) so a held key doesn’t toggle repeatedly. For only-second updates the remaining-counter approach is simplest; for better accuracy prefer Stopwatch (or System.Timers.Timer + UI invoke).

Recommended Answers

All 3 Replies

Member Avatar for Member #119018

Well, think of it this way. If the user presses A, you want the timer's enabled property to be the opposite of what it currently is.

In Visual Basic, there is a Not keyword which logically negates an expression.

So, you're pseudocode would probably look like this:

If (theButton was A) Then
timer.Enabled = Not Timer.Enabled

Thanks for the suggestion. While that did in fact pause the countdown, the timer continued its counting even though it wasn't displaying it. I.e. when "A" was pressed, it did pause it, but if i waited for example 15 seconds while it was paused, and then pressed "A" again to resume the countdown, the count was actually exactly where it would have been if i hadn't pressed pause. Any ideas?

PrivateSub Me_KeyDown(ByVal sender AsObject, ByVal e As System.Windows.Forms.KeyEventArgs) HandlesMe.KeyDown
If e.KeyCode = Keys.B Then
Timer1.Enabled = True
CountDownStart = Microsoft.VisualBasic.DateAndTime.Timer
ElseIf e.KeyCode = Keys.A Then
Timer1.Enabled = Not Timer1.Enabled
End If
End Sub

Chad,
Try something along these lines.

Private StartTime As Integer = 100

    Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
        If e.KeyCode = Keys.A Then
            Timer1.Enabled = Not Timer1.Enabled
            e.Handled = True
        End If
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Timer1.Interval = 1000
        Timer1.Enabled = True
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        StartTime -= 1
        Label1.Text = CStr(StartTime)
    End Sub

It counts down a variable called StartTime. It is done each second. When the timer is disabled then the countdown stops also.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.