Progress bar not updating on a separate form - vb.net

I am trying to make a progress bar on a separate form when doing other tasks in my application. everything opens up and shows correctly but progress bar is not updating. I tried background worker with no joy. Code is in VB.net
Please help. I must be missing a step or two in my code.
What I am trying to do is when listview is clicked, takes a bit to populate textboxes out of my excel database, so I would like the another form to open and update progress bar accordingly.
Hope someone can help.
This is my Click Event:
Private Sub ListView1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListView1.SelectedIndexChanged
Application.EnableVisualStyles()
BackgroundWorker1.RunWorkerAsync()
frmProgress.Show()
AddToDatabaseToolStripMenuItem.Enabled = False
frmProgress.Close()
End Sub
Then I have Background Worker code as follows:
Private Sub backgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
For i As Integer = 1 To 100
showData()
Thread.Sleep(1000)
BackgroundWorker1.ReportProgress(CInt(100 * i / 100), "Running..." & i.ToString)
Next
End Sub
Private Sub backgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs)
frmProgress.ProgressBar1.Value = e.ProgressPercentage
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object,
ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
Handles BackgroundWorker1.RunWorkerCompleted
' Called when the BackgroundWorker is completed.
Label1.Text = "Loading... Done"
End Sub
Then my Progress form Load event is this:
Private Sub frmProgress_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Application.EnableVisualStyles()
With ProgressBar1
.Style = ProgressBarStyle.Blocks
.Visible = True
End With
Me.Text = "IDB"
Label1.Text = "Loading... Please wait"
Me.Cursor = Cursors.WaitCursor
End Sub
ShowData() is in the module and is the code that is loading and takes few seconds to load.
Thank you for your help.

Related

notification popup when new data is added to the DataGridview vb.net

I am building a standalone application with MS Access as the database. When I update the data from the application, I want the data in the DataGridView to also be updated on all of the other computers that are running the application. For that I have LoadData() but when a new ROW is added I am not getting the notification popup.
I really appreciate any help. Thanks in advance. I am not a pro in coding.
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
LoadData()
End Sub
Private Sub dgvNotify_RowsAdded(sender As Object, e As DataGridViewRowsAddedEventArgs) Handles dgvNotify.RowsAdded
Dim targetRow = Me.dgvNotify.Rows.Cast(Of DataGridViewRow)().OrderByDescending(Function(r) r.Cells("ID").Value).FirstOrDefault
If targetRow IsNot Nothing Then
targetRow.Selected = True
New_Notification()
End If
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
Me.WindowState = FormWindowState.Minimized
Me.Visible = False
e.Cancel = True
End Sub
Private Sub New_Notification()
NotifyIcon1.BalloonTipTitle = "New Important Notification"
NotifyIcon1.BalloonTipText = "Open the notification application to check the notifications" & vbCrLf & "If you have any question reachout to ops leads:)"
NotifyIcon1.ShowBalloonTip(3000)
End Sub

VB Showing progress in a Label on Form1

I have a Form1 with a "Rename" button: btnRename.
On Form1 I also have a label: lblProgress
Private Sub btnRename_Click(sender As Object, e As EventArgs) Handles btnRename.Click
Call Do_Rename()
Me.Close()
End Sub
Private Sub Do_Rename()
Call Get_File_names()
digits = 5
lblProgress.Text = "1 of 15"
Call Renumbering()
End Sub
When I click on the "Rename" button I want
to do some file renaming
to show progress like:
1 of 18
5 of 18
10 of 18
15 of 18
When I set: lblProgress.Text = "1 of 18", nothing shows up on the form!
You should do the following:
Create a BackgroundWorker
Call RunWorkerAsync in the button's click event
In the DoWork event of the BackgroundWorker, loop over the files to do your file renaming
Call ReportProgress in the loop based on the currently iterated file
In the ProgressChanged event of the BackgroundWorker, update the label's text based on the data sent back from the ReportProgress method
Example:
Private Sub btnRename_Click(sender As Object, e As EventArgs) Handles btnRename.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim worker = DirectCast(sender, BackgroundWorker)
For i = 0 To files.Count - 1
worker.ReportProgress(i, $"{i + 1} of {files.Count}")
' do your opeations on files
Next
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
lblProgress.Text = e.UserState.ToString()
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
lblProgress.Text = "BackgroundWorker completed."
End Sub
Add Doevents or Application.DoEvents() before and after change the label text or you can follow BackgroundWorker as mention by David.
Private Sub Do_Rename()
Call Get_File_names()
Application.DoEvents()
digits = 5
lblProgress.Text = "1 of 15"
Application.DoEvents()
Call Renumbering()
End Sub

Print Progress bar value to textbox

I'm trying to print a progressbar's percentage to a textbox. When ever I run my program, nothing appears in the textbox. This is my code:
Private Sub Button11_Click(sender As Object, e As EventArgs) Handles Button11.Click
ProgressBar1.Maximum = TextBox1.Text
End Sub
Help is very appreciated! Thank you.
Here is some code that i have written up for you to have a look at, it should lead you in the right direction and help you on your way :)
Imports System.ComponentModel
Public Class Form1
''This will display the information to the textbox and will also load a progressbar(you can change it to something else beside a textbox too eg label, windows form title and so on).
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
TextBox1.Text = e.ProgressPercentage & "%"
ProgressBar1.Value = e.ProgressPercentage
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
''This is make the backgroundworker start at load up(change it to a button if need be
CheckForIllegalCrossThreadCalls = False
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
''This is the example that i created to show you how to set a task.
For i = 0 To 10000
TextBox1.Text = i
BackgroundWorker1.ReportProgress(i)
System.Threading.Thread.Sleep(500)
Next
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
''once the task is complete it will show a messagebox and reset the progressbars value to 0 so its not full when the task is compelete.
MessageBox.Show("Completed")
ProgressBar1.Value = 0
End Sub
End Class
Let me know how you go, i live in a country where i cant access the website link that you posted.Happy Coding
UPDATE: do check out the backgroundworkers on google, there are a lot of tutorials to help you :)

Button Click Event Within Another

I have two buttons Start button and Stop button .I run my program by clicking on start button. I want to stop the program during the start button . But the program will not responde until the start buttun finish its job. How i can do check the stop buttun during the start. i heard about threading but i do not know how i can do it.
Private Sub Button_Start (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
//my code
//check always if the user push stop if no continue if yes go to this sub
//my code
end sub
Private Sub Button_Stop (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
stopClick = True
Dim Response As Integer
Response = MessageBox.Show("Do you really want to exit?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
If Response = vbYes Then
Me.Close()
End If
End Sub
you can use threading put button1 code in a function and use the thread .
you can refer to this example
'Thread created to handle the Background process for start_function
Dim t As System.Threading.Thread
Private Sub start_function()
While True
'your code here for Eg:
Dim i As Integer
i = i + 1
End While
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
t = New System.Threading.Thread(AddressOf Me.start_function)
t.Start()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
t.Abort()
End Sub
Drag a backgroundworker component onto your form.
Imports System.ComponentModel
Public Class Form1
Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
Me.Text = "Busy Doing Work"
BackgroundWorker1.WorkerSupportsCancellation = True
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click
Me.Text = "Asking to Cancel"
BackgroundWorker1.CancelAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
While Not BackgroundWorker1.CancellationPending
System.Threading.Thread.Sleep(1000)
End While
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Me.Text = "Cancelled"
End Sub
End Class

How to use timer for for next loop in visual basic 2008

I have a case where i need to generate millions of unique codes. For this I have created a generate function where the random number is generated. I call this function from a for loop and add the generated number on a list box. my code is as follow
for i=1 to val(txtnumber.txt)
mynum=generate()
next
I have created a lable on form where i wanted to display the no of secs elapsed while processing the loop. I used timer control as
timer1.start()
for i=1 to val(txtnumber.text)
mynum=generate()
listbox1.items.add(mynum)
next
timer1.stop
and on timer1_tick function
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Label1.Text = Val(Label1.Text) + 1
End Sub
but when i click generate button, all numbers are generated, but timer doesnot shows time elapsed.
I may have missed something, so please help me out
This is probably best handled in a BackgroundWorker. Place one on the form and set its WorkerReportsProgress=True. Also, placing a million numbers in a ListBox probably isn't a good idea, so I omitted that.
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
Button1.Enabled = False
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim started As DateTime = Now
For i As Integer = 1 To val(txtnumber.txt)
mynum=generate()
BackgroundWorker1.ReportProgress(i, Nothing)
Next
Dim ended As TimeSpan = Now.Subtract(started)
BackgroundWorker1.ReportProgress(0, ended.TotalSeconds.ToString)
End Sub
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
If e.UserState IsNot Nothing Then
Label1.Text = e.UserState.ToString()
Else
Label1.Text = e.ProgressPercentage.ToString
End If
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Button1.Enabled = True
End Sub
Your label should be updating correctly when the worker reports the ProgressChanged event.
What you're encountering is a threading issue. The work you are doing to generate the numbers is being executing by the UI thread, so it never gets a chance to update the screen. Take a look here: How to prevent UI from freezing during lengthy process?
This one might also have good information for you: Updating UI from another thread
Try this:
Private _Counter As Integer = 0
Private _StartTime As Date = Now
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
_StartTime = Now
_Counter = CInt(Val(txtnumber.Text))
ListBox1.Items.Clear()
Label1.Text = "0"
Timer1.Interval = 50
Timer1.Start()
End Sub
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
ListBox1.Items.Add(generate())
Label1.Text = New Date((Now - _StartTime).Ticks).ToString("HH:mm:ss.ff")
_Counter -= 1
If (_Counter <= 0) Then
Timer1.Stop()
End If
End Sub
Or you can research actual Threading.