I have to create multiple timer "n" times with handler.
Which will be stored for a row in my DataGrid.
For each row there will be a timer that works seperately.
What I thought of looks like:
Private Sub CreateTimer()
Dim tmr As New Timer
tmr.Interval = 1000 '1 Second
tmr.Enabled = True
AddHandler tmr.Tick, AddressOf GlobalTimerTick
End Sub
'A timer tick handler that would work for each timer I add with the sub above
'All timers I created should work seperately
Private Sub GlobalTimerTick(TheTimer as Timer, ByVal sender As Object, ByVal e As EventArgs)
mynumber = mynumber + 1
With DataGridView1
.Rows(n).Cells(4).Value = mynumber " saniye"
End With
End Sub
So how can I achieve this?
I believe Tag property of Timer would work beautifully in your case. I don't have my IDE currently, but the following snippet should give you the idea.
Private Sub CreateTimer()
Dim tmr As New Timer
tmr.Interval = 1000 '1 Second
tmr.Enabled = True
tmr.Tag = ROW_INDEX
AddHandler tmr.Tick, AddressOf GlobalTimerTick
End Sub
'A timer tick handler that would work for each timer I add with the sub above
'All timers I created should work seperately
Private Sub GlobalTimerTick(ByVal sender As Object, ByVal e As EventArgs)
mynumber = sender.Tag
With DataGridView1
.Rows(n).Cells(4).Value = mynumber " saniye"
End With
End Sub
Related
I want the vb.net app to close after 1 minute of inactive time.
this code will close the app after 1 min for active user as well.
Dim app As Application
Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim aTimer As System.Timers.Timer
aTimer = New System.Timers.Timer()
aTimer.Interval = 60000
AddHandler aTimer.Elapsed, AddressOf OnTimedEvent
aTimer.Enabled = True
End Sub
Private Sub OnTimedEvent(ByVal source As Object, ByVal e As System.Timers.ElapsedEventArgs)
app.Exit()
End Sub
You can try as follow.
Create a System.Timers.Timerin your window.xaml.vb file:
Private WithEvents CloseTimer As New Timers.Timer
In the constructor, add the following lines:
CloseTimer.Interval = 1000 * 5 ' Remember that interval is set in milliseconds
CloseTimer.Start()
Every time the mouse is moved on the window, the timer has to be reset, so use the MouseMove event like this:
Private Sub Window_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
ResetTimer()
End Sub
And define the ResetTimer() subroutine as follow:
Private Sub ResetTimer()
CloseTimer.Stop()
CloseTimer.Start()
End Sub
Obviously you can change / improve that condition: for example, if the user doesn't move the mouse because he's typing in a Textbox, you should manage this condition, too:
Private Sub Window_PreviewKeyDown() Handles Me.PreviewKeyDown
ResetTimer()
End Sub
This will catch all KeyDown event from the window and all its children controls.
Finally add the Timer_Elapsed event, which will be fired when the timer interval elapsed:
Private Shared Sub Timer_Elapsed() Handles CloseTimer.Elapsed
Environment.Exit(0)
End Sub
If you notice there are more conditions to keep the application running, just find the appropriate event and in its subscription call ResetTimer().
Note that this method is quite simple but, depending on the architecture of the application, there may be better methods.
I create timers within a class
Dim timer As New Timer
timer.Enabled = True
timer.Interval = 1000
timer.Tag = "TimeslipTimer_" & timeslip.id
AddHandler timer.Tick, AddressOf GlobalTimerTick
timer.Start()
The problem i have is how can I delete those if I needed?
At the moment I was looking to add timers to a list, similar to below, but i didnt work out
dim timers as new list(of Timer)
For Each c As Timer In Timers
c.Dispose()
Timers.Remove(c)
Next
When removing from a list the list must be accessed in reverse order. Also remember to remove the handler.
Public Class Form1
Private WithEvents timer As Timer
Private timers As New List(Of Timer)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
timer = New Timer
timers.Add(timer)
timer.Enabled = True
timer.Interval = 1000
'timer.Tag = "TimeslipTimer_" & timeslip.id
AddHandler timer.Tick, AddressOf GlobalTimerTick
timer.Start()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For x As Integer = timers.Count - 1 To 0 Step -1
Dim t As Timer = timers(x)
RemoveHandler t.Tick, AddressOf GlobalTimerTick
t.Stop()
t.Dispose()
timers.RemoveAt(x)
Next
End Sub
Private Sub GlobalTimerTick(sender As Object, e As EventArgs)
Debug.WriteLine("TICK")
End Sub
End Class
Private Time As New Timer
Private Sub btnWood_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnWood.Click
prgWood.Value = 0
Time.Interval = 1000
Time.Start()
AddHandler Time.Tick, AddressOf IncreaseProgressBar
If prgWood.Value <> prgWood.Maximum Then
btnWood.Enabled = False
End If
Dim intAmountofWood As Integer = 11 * Rnd() + 10
intWood = intWood + intAmountofWood
Me.lblWoodAmount.Text = intWood
Private Sub IncreaseProgressBar(ByVal sender As Object, ByVal e As EventArgs)
prgWood.Increment(10)
If prgWood.Value = prgWood.Maximum Then
prgWood.Increment(0)
Time.Stop()
btnWood.Enabled = True
End If
End Sub
For my progress bar, I use a Timer to increment the value by 10 every 1 second. When I debug the project, it works fine the first time (taking 10 seconds for the progress bar to complete) but when I click the button a second time, it only takes 5 seconds, then less and less each time. This code is for an incremental game I'm trying to make for school.
From LarsTech's comment:
Public Class Form1
Private Time As New Timer
Public Sub New()
'Initialisation, etc
AddHandler Time.Tick, AddressOf IncreaseProgressBar
End Sub
'Other methods, etc
End Class
Then you need to remove the AddHandler from the button
click event
Can you do this?
Create a sub and add this code
`
ProgressBar1.Value = e.ProgressPercentage
If ProgressBar1.Value = ProgressBar1.Maximum Then
ProgressBar1.Value = ProgressBar1.Minimum
End If
`
then call that sub here.
`Private Sub btnWood_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnWood.Click
'**Name of the Sub**
prgWood.Value = 0
Time.Interval = 1000
Time.Start()
AddHandler Time.Tick, AddressOf IncreaseProgressBar
If prgWood.Value <> prgWood.Maximum Then
btnWood.Enabled = False
End If
Dim intAmountofWood As Integer = 11 * Rnd() + 10
intWood = intWood + intAmountofWood
Me.lblWoodAmount.Text = intWood
End Sub
`
let see if that one works
I have a panel with 50 button and 1 label in my form
Private Sub flp_table_paint(sender As Object, e As PaintEventArgs) Handles flp_table.Paint
Dim i As Integer
For i = 1 To 50
Dim btn_tableNo As New Button
btn_tableNo.Width = 40
btn_tableNo.Height = 40
btn_tableNo.Text = i
AddHandler btn_tableNo.Click, AddressOf TableButtonClicked
Dim timer As New Timer
timer.Tag = i
Me.flp_table.Controls.Add(btn_tableNo)
Next
End Sub
What I try to do is, for every single button that i clicked they will start their own timer and show on the label.
Example:
11:00:00PM - Clicked on Button1 , lb_timer will show 1,2,3,4...
11:00:30PM - Clicked on Button2 , lb_timer will show 1,2,3,4...
11:00:45PM - Clicked on Button1 again, lb_timer will show 45,46,47,48...
11:00:50PM - Clicked on Button2 again, lb_timer will show 20,21,22,23...
Here is what i try so far, but fail...
Private Sub TableButtonClicked(ByVal sender As Object, ByVal e As EventArgs)
Dim currButton As Button = sender
selectedTable = currButton
For Each timer As Timer In Me.Controls
If timer.Tag = selectedTable.Text Then
timer.Start()
lb_timer.Text = timer.ToString
End If
Next
End Sub
I have no idea how to make it work, please help me...
Here asynchronous approach without Timer and one eventhandler for all buttons
' In constructor
AddHandler button1.Click, AddressOf Button_Click
AddHandler button2.Click, AddressOf Button_Click
AddHandler button3.Click, AddressOf Button_Click
' ... rest of buttons
' variable will keep name of the button which number is showing
Private _selectedButtonName As String
Private Async Sub Button_Click(sender As object, e As EventArgs)
Dim button As Button = DirectCast(sender, Button)
_selectedButtonName = button.Name
Dim isRunning As Boolean = (button.Tag IsNot Nothing)
If isRunning = True Then return
await StartCounterAsync(button)
End Sub
Private Async Function StartCounterAsync(Button button) As Task
button.Tag = new object()
Dim number As Integer = 0
While True
await Task.Delay(1000)
number += 1
If _selectedButtonName.Equals(button.Name)
lb_timer.Text = $"{button.Name}: {number}"
End If
End While
End Function
You can add CancellationToken in case you want reset counters.
Sadly the timer doesn't show elapsed time. An easier control to use for your purpose would be the StopWatch control. Its quite similar and will show a running time.
Dim StopWatchTest As New Stopwatch
StopWatchTest.Start()
Dim EllapsedTime As String = StopWatchTest.ElapsedMilliseconds / 1000
However since you want to continually update the label with the ellapsed time, you would need a timer to update the label at every tick.
Dim UpdateLabelTimer As New Timer()
UpdateLabelTimer.Interval = 1000 'How often to update your label (in milliseconds)
AddHandler UpdateLabelTimer.Tick, AddressOf Tick
UpdateLabelTimer.Start()
----------
Private Sub Tick()
lblLabel.text = StopWatchTest.ElapsedMilliseconds
End Sub
I could easily close form after few seconds; but when I want to close many forms one after another, same sequence as they were "created"; I could not figure it out:
The main form code is as below:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim numberOfForms As Integer = 10
For open = 1 To numberOfForms
TestClosing()
Next
End Sub
The module code that I am trying to create then close forms after few seconds is as below:
Imports System.Timers
Module ClosingModule
Sub TestClosing()
Dim frmNew As New Form
frmNew.Show()
Dim tmr As New System.Timers.Timer()
tmr.Interval = 3000
tmr.Enabled = True
tmr.Start()
End Sub
End Module
I started a timer, but all the methods I tried to close the form is same sequence they were created; were not successful;
Help appreciated; and thanks in advance.
Add the Timer to the Forms you are creating, start it when the Form is created that way they will be closed in the same order that they were created. I also added an incremental delay to that the order of closing is more evident.
Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim numberOfForms As Integer = 10
For open = 1 To numberOfForms
Dim frmNew As New Form2
frmNew.Text = open.ToString
frmNew.Show()
Next
End Sub
Form2
Public Class Form2
Dim myTimer As New Timer()
Private Sub myTimer_Tick(sender As System.Object, e As System.EventArgs)
myTimer.Stop()
Me.Close()
End Sub
Private Sub Form2_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
myTimer.Interval = 1000 * CInt(Me.Text)
AddHandler myTimer.Tick, AddressOf myTimer_Tick
myTimer.Start()
End Sub
End Class
Added code in module to do the same thing:
Imports System.Timers
Module ClosingModule
Sub TestClosing(multiplier As Integer)
Dim frmNew As New Form
frmNew.Show()
Dim tmr As New System.Timers.Timer()
AddHandler tmr.Elapsed, AddressOf Timer_Elapsed 'Add Handler to New Timer
tmr.SynchronizingObject = frmNew 'Synchronize Timer to newly created form
tmr.Interval = 1000 * multiplier
tmr.Enabled = True
tmr.Start()
End Sub
Public Sub Timer_Elapsed(sender As Object, e As ElapsedEventArgs)
Dim tmr As System.Timers.Timer = DirectCast(sender, System.Timers.Timer)
tmr.Stop() 'Stop Timer
DirectCast(tmr.SynchronizingObject, Form).Close() 'Get Form Timer was synchronized with and close it
tmr.SynchronizingObject = Nothing 'Remove Form reference from timer
RemoveHandler tmr.Elapsed, AddressOf Timer_Elapsed 'Remove Handler from Timer
End Sub