Timer: Elapsed event doesn't trigger

I've started learning vb.net and created a custom timer class. The problem is that the elapsed event doesn't trigger. Can anybody tell me why this is the case?

Option Strict On

Public Class Form1

Dim WithEvents MyTimer As CustomTimer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

MyTimer = New CustomTimer()

End Sub


Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
MyTimer.HourLeft = Convert.ToInt32(TimePicker.Value.Hour)
MyTimer.MinuteLeft = Convert.ToInt32(TimePicker.Value.Minute)
MyTimer.SecondLeft = Convert.ToInt32(TimePicker.Value.Second)

Call MyTimer.SetTimerLabel()

MyTimer.Interval = 1000
MyTimer.Start()

End Sub

Private Sub MyTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles MyTimer.Elapsed
Call MyTimer.TimerCountdown()
End Sub
End Class

Option Strict On

Public Class CustomTimer

Inherits System.Timers.Timer

'timer properties
Private m_HourLeft As Integer
Private m_MinuteLeft As Integer
Private m_SecondLeft As Integer


Public Sub New()
'initialize countdown values and call SetTimerLabel to set the timer to default values
HourLeft = 0
MinuteLeft = 0
SecondLeft = 0

Call SetTimerLabel()

End Sub

Public Property HourLeft() As Integer
Get
Return m_HourLeft
End Get
Set(ByVal value As Integer)
m_HourLeft = value
End Set
End Property

Public Property MinuteLeft() As Integer
Get
Return m_MinuteLeft
End Get
Set(ByVal value As Integer)
m_MinuteLeft = value
End Set
End Property

Public Property SecondLeft() As Integer
Get
Return m_SecondLeft
End Get
Set(ByVal value As Integer)
m_SecondLeft = value
End Set
End Property


Public Sub SetTimerLabel()

'Create displayvariables (as strings)
'and add zeros if necessary for correct (double digit) display
Dim HourLeftString As String = m_HourLeft.ToString
Dim MinuteLeftString As String = m_MinuteLeft.ToString
Dim SecondLeftString As String = m_SecondLeft.ToString

If HourLeftString.Length = 1 Then HourLeftString = "0" & HourLeftString
If MinuteLeftString.Length = 1 Then MinuteLeftString = "0" & MinuteLeftString
If SecondLeftString.Length = 1 Then SecondLeftString = "0" & SecondLeftString

'Set timer countdown window
Form1.lblCountdown.Text = HourLeftString & " : " & MinuteLeftString & " : " & SecondLeftString

End Sub

Public Sub TimerCountdown()
'for testing purposes, still incomplete...
m_SecondLeft = m_SecondLeft - 1
Call SetTimerLabel()
End Sub
End Class

Create a lblCountdown on the form and a btnStart. Also add a timepicker control with the format property set to time. To see the problem, execute the program, enter some digit in the second box and hit btnStart. The value will not countdown like specified in the TimerCountdown method.

[3285 byte] By [JanMichiel] at [2007-12-24]
# 1

make sure you also enable it just in case:

MyTimer.Enabled = true

ahmedilyas at 2007-8-31 > top of Msdn Tech,Visual Basic,Visual Basic General...
# 2

Thank you for your reply, but that doesn't work. Which is logical as the Start event should already set the enabled property to true.

Btw. about controls, should I view a control as an instance of a class. i.e. an object? And what is the difference between controls and components?

I could send someone the project if that would help fixing my problem.

JanMichiel at 2007-8-31 > top of Msdn Tech,Visual Basic,Visual Basic General...
# 3

This line here is your culprit:

Form1.lblCountdown.Text = HourLeftString & " : " & MinuteLeftString & " : " & SecondLeftString

First problem is the instance of the form is not the same...the second problem is You can not manipulate the UI thread from another thread...in this cae the timer is on another thread...

The correct procedure for what you are trying to would be to override the elapsed event and insert your own event arguments which would be the label information...so when the event is fired the event arguments sends the data back to the event hadler in the main form and from there you can set the label

pseudo:

Private Sub MyTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles MyTimer.Elapsed
Me.CountdownLabel.text = e.LabelArg

End Sub
End Class

now with all that being said...you may find it alot easier just to drop a timer component on your form and contain your methods within form1...the following code encsed in form 1 works...


Public Class Form1

Private m_HourLeft As Integer

Private m_MinuteLeft As Integer

Private m_SecondLeft As Integer

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

HourLeft = 0
MinuteLeft = 0
SecondLeft = 0
End Sub

Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

Me.Timer1.Enabled = True

Me.HourLeft = Convert.ToInt32(TimePicker.Value.Hour)
Me.MinuteLeft = Convert.ToInt32(TimePicker.Value.Minute)
Me.SecondLeft = Convert.ToInt32(TimePicker.Value.Second)
Call Me.SetTimerLabel()
Me.Timer1.Interval = 1000
Me.Timer1.Start()
End Sub

Public Sub SetTimerLabel()
'Create displayvariables (as strings)

'and add zeros if necessary for correct (double digit) display

Dim HourLeftString As String = m_HourLeft.ToString

Dim MinuteLeftString As String = m_MinuteLeft.ToString

Dim SecondLeftString As String = m_SecondLeft.ToString

If HourLeftString.Length = 1 Then HourLeftString = "0" & HourLeftString

If MinuteLeftString.Length = 1 Then MinuteLeftString = "0" & MinuteLeftString

If SecondLeftString.Length = 1 Then SecondLeftString = "0" & SecondLeftString

'Set timer countdown window

Me.lblCountdown.Text = HourLeftString & " : " & MinuteLeftString & " : " & SecondLeftString

End Sub

Public Sub TimerCountdown()
'for testing purposes, still incomplete...

m_SecondLeft = m_SecondLeft - 1
Call SetTimerLabel()
End Sub

Public Property HourLeft() As Integer

Get

Return m_HourLeft

End Get

Set(ByVal value As Integer)
m_HourLeft = value

End Set

End Property

Public Property MinuteLeft() As Integer

Get

Return m_MinuteLeft

End Get

Set(ByVal value As Integer)
m_MinuteLeft = value

End Set

End Property

Public Property SecondLeft() As Integer

Get

Return m_SecondLeft

End Get

Set(ByVal value As Integer)
m_SecondLeft = value

End Set

End Property

Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick

Me.TimerCountdown()
End Sub
End
Class

DMan1 at 2007-8-31 > top of Msdn Tech,Visual Basic,Visual Basic General...
# 4

Thanks for your reply. What you said is still over my head. I know using a timer control is a lot easier, but I wanted to do it this way to see if I could do it. Guess not . I'll just let it rest and use the control for now. Maybe when I'm a bit more advanced in the visual basic material I'll understand. Thanks anyway.

JanMichiel at 2007-8-31 > top of Msdn Tech,Visual Basic,Visual Basic General...
# 5

Here is a good place to start learning about events....

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconeventsmini-sample.asp

your timer class code was good with the exception of the cross-thread call(updating the label from the timer thread)...take a look at the sample and documentation and see if you can get a better grip on overriding the elapsed event and creating your own arguments to pass back to the event handler

HTH

DMan1 at 2007-8-31 > top of Msdn Tech,Visual Basic,Visual Basic General...