net program that uses excel as a datasource. I then fill a datagridview with this datasource and make changes to the dataset via the datagridview. I'm trying to find a way to refresh this dataset via a button that will update the values after a change. My only problem is that I'm trying to set up a timer in my refresh method but it never initializes/starts. I can't figure out why, from what I've found online the way to start a timer in vb.net is to set the timer variable to enabled = true. I've stepped into my debugger and found that the timer never starts. Here is my code below, if there is anyone who can figure out why this timer isn't starting I would greatly appreciate your help!
Dim mytimer As New System.Timers.Timer
Sub refresh()
write2Size()
mytimer.timer = New System.Timers.Timer(20000)
'Starting Timer
mytimer.Enabled = True
Cursor.Current = Cursors.WaitCursor
AddHandler mytimer.Elapsed, AddressOf OnTimedEvent
objworkbook.Save()
objExcel.ActiveWorkbook.Save()
myDS.Clear()
retrieveUpdate()
'Setting the cursor back to normal here
Cursor.Current = Cursors.Default
End Sub
Private Shared Sub OnTimedEvent(source As Object, e As ElapsedEventArgs)
Console.WriteLine("The Elapsed event was raised at {0}, e.SignalTime)
End Sub
You are creating a timer here
Dim mytimer As New System.Timers.Timer
but you only assign a handler to the one you create inside the Refresh routine.
Would have expected
Dim mytimer As New System.Timers.Timer(20000)
AddHandler mytimer.Elapsed, AddressOf OnTimedEvent
then
Private Shared Sub OnTimedEvent(source As Object, e As ElapsedEventArgs)
Console.WriteLine("The Elapsed event was raised at {0}, e.SignalTime)
Refresh()
End Sub
and something like
Sub refresh()
myTimer.Enabled = False
// refresh the doings
myTimer.Enabled = True
End sub
Excuse the lack of VBness, I'm a C# boy.
Related
I want to display an image for 1 second and then disappear it. The code i'm trying to use is:
PictureBox4.Visible = True
System.Threading.Thread.Sleep(1000) ' 1 second delay
PictureBox4.Visible = False
But so far it's not working, is there a way to make this code works or any other methods to implement a delay in vb.net?
The reason why your code isn't working is because Sleep is tying up the UI thread and the control is never redrawn. So technically the Visible property is being changed, it is just that the user never sees the change.
You have a couple of options. One is to use a System.Timers.Timer (documentation) and set the AutoReset to false and the Interval to 1,000. Before you start the timer you would show the control and then in the Timer's Elapsed event you would hide the control. Here is a quick example:
Private ReadOnly _timer As Timers.Timer
Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
_timer = New Timers.Timer() With {
.AutoReset = False,
.Interval = 1000,
.SynchronizingObject = Me
}
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' create an event handler for the Elapsed event
AddHandler _timer.Elapsed, Sub() PictureBox4.Hide()
' show the control then start the timer
PictureBox4.Show()
_timer.Start()
End Sub
Update
Per JMcIlhinney's suggestion, I'm setting the SynchronizingObject property so that you don't have to call the Invoke method when hiding the control.
Try this
PictureBox4.Visible = True
Application.DoEvents()
System.Threading.Thread.Sleep(1000)
PictureBox4.Visible = False
I'm new to the programming world.
I'm trying to make a simple software which will go through 5-6 forms (showing the progress bar as a picture) and on each form display progress as a picture while some other code is being run in the background. I've written my code and it just keeps looping the application for some reason and I don't know how to stop it from looping.
As I said, I'm new to visual basic and programming world, so please just go easy on me, thanks!
I just need help with stopping the timer after the HandleTimerTick() happens. I don't know how to call the timer to stop, from the previous sub or something. So, I just need a command to stop t.Tick once HandleTimerTick from the second sub starts.
If you have any simpler command to stop the code from executing for the number of seconds feel free to share. Thanks in advance!
Private Sub Delay1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim t As Timer = New Timer()
t.Interval = 2000
AddHandler t.Tick, AddressOf HandleTimerTick
t.Start()
End Sub
Private Sub HandleTimerTick()
Dim SecondForm As New Delay2
SecondForm.Show()
Me.Close()
End Sub
Use the proper signature for the Event handler In this way you get a reference to the Timer that trigger the event handler and you can stop it
Private Sub HandleTimerTick(sender As Object, e As EventArgs)
... your code to handle the event
' Stop the timer
Dim t As System.Windows.Forms.Timer
t = DirectCast(sender, System.Windows.Forms.Timer)
t.Stop
End Sub
I want to specify in a text field how many timers I want to add to my form and specify the code that should be into the timer.
For instance: My textbox says "2" and then I click a button and it creates two timers and adds a specific source code for both timers.
I have tried different codes and while they worked, I wasn't able to specify the number of controls on a form to create.
How can I achieve this efficiently?
Thanks
Just to create one timer
Public Class Form1
private _timer as Windows.Forms.Timer
...
Public Sub New()
...
_timer = New Timer(Me)
_timer.Interval = 1000 'Timer will trigger one second after start
AddHandler _timer.tick, AddressOf Timer_tick 'Timer will call this sub when done
End Sub
Sub Button_click(sender as Object, e as EventArgs)
_timer.Start() 'Start the timer
...
End Sub
Private Sub Timer_tick(sender as Object, e as EventArgs)
MessageBox.Show("Timerrr!!")
End Sub
...
End Class
Now if you want to create more than one timer, you can use an array of Timer.
In this case, I used a form conatining a NumericUpDown controll element, a button and a label, plus two labels which only contain text.See this picture
To create the timers, I use the function add_timers(timercount), which looks like this:
Function add_timers(timercount As Integer)
'Using a loop to creat <timercount> timers
For g As Integer = 1 To timercount
'Creating new timer 't'
Dim t As New Timer()
'setting interval of t
t.Interval = 1000
'Enabling timer
t.Enabled = True
'Code which runs when t ticks
AddHandler t.Tick, AddressOf TimerTick
Next
End Function
This function gets called when Button1, the start button gets pressed. It uses NumericUpDown1.Value as the parameter for the function. The function uses a loop to create new timers t, sets their intervals and the code to run when they tick.
Unfourtunately, I didn't find a way to dynamically create code, so every timer performs the same action. Using arrays and loops in a clever way might enable you to use different value for each timer. To create code for the timer use a Sub:
Sub TimerTick(ByVal sender As Object, e As EventArgs)
'Add your code here
Label1.Text += 1
End Sub
The complete code I use is:
Public Class Form1
Function add_timers(timercount As Integer)
'Using a loop to creat <timercount> timers
For g As Integer = 1 To timercount
'Creating new timer 't'
Dim t As New Timer()
'setting interval of t
t.Interval = 1000
'Enabling timer
t.Enabled = True
'Code which runs when t ticks
AddHandler t.Tick, AddressOf TimerTick
Next
End Function
Sub TimerTick(ByVal sender As Object, e As EventArgs)
'Add your code here
Label1.Text += 1
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
add_timers(NumericUpDown1.Value)
End Sub
End Class
Packing the timers into an array is possible, that way you can easily access each timer with its index. Serach for it on the internet, and if you then have no idea of how to do it, tell me in the comments.
My button is responding to clicks while disabled.
Private Sub btnGenerate_Click(sender As Object, e As EventArgs) Handles btnGenerate.Click
btnGenerate.Enabled = False
Me.Cursor = Cursors.WaitCursor
'Do a bunch of operations
Me.Cursor = Cursors.Default
btnGenerate.Enabled = True
End Sub
It takes about 5-10 seconds to process the stuff I'm doing in the background. During that 5-10 seconds the button is greyed out, but if I click it a second time, then it performs the operational stuff a second time after finishing the first.
I'm missing something here. How can I prevent button from allowing interaction until operations are finished?
Dim Working as boolean=false
Private Sub btnGenerate_Click(sender As Object, e As EventArgs) Handles btnGenerate.Click
if Working=true then exit sub
' Your Work Process
Work()
End Sub
sub Work()
Working=True
' Work code
Working=False
end sub
this should prevent the double click
With VS2012, Async Work is very easy to use (compared to previous versions...).
The problem is the UI thread is not letting go. Without seeing what 'work' is actually going on, I can not explain why. I am hoping nothing that re enables the button...
However, Async will allow release of the UI thread and the enabled = false should take effect. Try something like this:
Private Async Sub btnGenerate_Click(sender As Object, e As EventArgs) Handles btnGenerate.Click
btnGenerate.Enabled = False
Dim t As New Task(Sub() MyWorkLoad())
t.Start()
Await t
btnGenerate.Enabled = True
End Sub
Private Sub MyWorkLoad()
'do your work here
'for testing
Dim time As Date = Now
Do While True
If DateAdd(DateInterval.Second, -5, Now) > time Then Exit Do
Loop
End Sub
This did work for me...
I did this first into a WinForm project, now I've changed the application type to "Console application", I've deleted the form1.vb, changed the startup object to this "Module1.vb" but now I can't run the app.
well the app runs but the timer tick is doing nothing, the code is exactly the same, I only did one change for the sub main/form1_load name
What I'm doing wrong?
PS: I've tested if the error was in the conditional of the lock method and all is good there, the problem is with the ticker event but I don't know why.
#Region " Vars "
Dim Running As Boolean = False
Dim Errors As Boolean = False
Dim Executable_Name As String = Nothing
Dim Toogle_Key As System.Windows.Forms.Keys = Nothing
Dim WithEvents Toogle_Key_Global As Shortcut = Nothing
Dim Executable_Timer As New Timer
Dim Lock_Timer As New Timer
Dim Lock_Interval As Int32 = 10
Dim Lock_Sleep As Int32 = Get_Milliseconds(3)
Dim Screen_Center_X As Int16 = (Screen.PrimaryScreen.Bounds.Width / 2)
Dim Screen_Center_Y As Int16 = (Screen.PrimaryScreen.Bounds.Height / 2)
#End Region
' Load
Sub main()
Pass_Args()
Sleep()
Lock()
End Sub
' Lock
Private Sub Lock()
If Process_Is_Running(Executable_Name) Then
AddHandler Lock_Timer.Tick, AddressOf Lock_Tick
AddHandler Executable_Timer.Tick, AddressOf Executable_Tick
Lock_Timer.Interval = Lock_Interval
Lock_Timer.Start()
Executable_Timer.Start()
Running = True
Else
Terminate()
End If
End Sub
' Lock Tick
Private Sub Lock_Tick()
Console.WriteLine("test")
If Running Then Cursor.Position = New Point(Screen_Center_X, Screen_Center_Y)
End Sub
UPDATE
I made these changes like in the examples of MSDN:
Dim Executable_Timer As New System.Timers.Timer
Dim Lock_Timer As New System.Timers.Timer
AddHandler Lock_Timer.Elapsed, AddressOf Lock_Tick
AddHandler Executable_Timer.Elapsed, AddressOf Executable_Tick
But the tick/elapsed is still doing nothing...
FROM MSDN
Windows.Forms.Timer
Implements a timer that raises an event at user-defined intervals.
This timer is optimized for use in Windows Forms applications and must
be used in a window.
You need a System.Timer
Of course this requires a different event Handling
(Example taken from MSDN)
' Create a timer with a ten second interval.
Dim aTimer = new System.Timers.Timer(10000)
' Hook up the Elapsed event for the timer.
AddHandler aTimer.Elapsed, AddressOf OnTimedEvent
....
Private Shared Sub OnTimedEvent(source As Object, e As ElapsedEventArgs)
Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime)
End Sub
You could use Windows.Forms.Timer in console application if you add Application.Run() at the end of your main().
This kind of timer might be useful in some console applications if you are using any offscreen Windows.Forms object - ie.: for offscreen rendering - these objects can't be simply accessed from System.Timer since it fires on separate thread (than the one where Windows.Forms object was created on).
Otherwise by all means use the System.Timers.Timer or System.Threading.Timer