Progress Bar and load dataset?

havinablast

Member
Joined
Dec 10, 2009
Messages
14
Programming Experience
Beginner
Okay....

so what I want to do should be pretty simple. I've been following the examples found here Using the BackgroundWorker Component - VBForums . I've been successful, but I'm not smart enough to put it in my project.

What I'd like to happen is this

1. I hit a button to load data from a dataset....

2. have a progress bar show until this action is complete.

The main problem is that I can't figure out how to tie the "progress bar" to the action of "pulling the dataset"

I'm sure this is a crazy question for you all, but hey...

Would I put all of the coding in the button_Click sub?
 
Before you start the work that has unknown progress you can set the ProgressBar Style to Marquee.
 
Thanks

Hi John,

Thanks for the reply. I actually had just read your suggestion in a post that you gave to someone else and decided to give it a try. This does seem to be the best method for loading databases.

Thank you for your help!
 
One more question

So... I'm trying to use the backgroundworker and it seems to work fine on the first go round. i.e.

1. the progress bar (marquee) is enabled/visible on click

2. work is performed in background

3. then the "work finished" part of the backgroundworker kicks in and...

4. the datagridview is filled AND the progress bar is set to .visible = false

all good....

BUT, if I clear the datagridview and then try to click the initiate button again, it will not fill.

following is the code that I have as of right now... (I'm not sure how to make this show up in a code box)

**********************

Public Class Form6
Dim WorkerON As Boolean 'xxxxxxx boolean added to make second click not possible

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.ProgressBar1.Visible = False
End Sub

'This method is executed in a worker thread.
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
Me.ContactTableAdapter.Fill(Me.DsTest.Contact)
End Sub


'This method is executed in the UI thread.
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Me.Label1.Text = "Operation complete"
WorkerON = False
ContactDataGridView.DataSource = DsTest.Contact
Me.Cursor = Cursors.Arrow
ProgressBar1.Visible = False
ProgressBar1.Enabled = False
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If WorkerON = False Then 'xxxxxxx boolean added to make second click not possible
ProgressBar1.Enabled = True
ProgressBar1.Visible = True
BackgroundWorker1.WorkerReportsProgress = False
BackgroundWorker1.WorkerSupportsCancellation = False
BackgroundWorker1.RunWorkerAsync()
Me.Cursor = Cursors.WaitCursor
WorkerON = True
ElseIf WorkerON = True Then
End If
End Sub

''xxxxxxxxxxxxxxxxxxxxxxxxxx clear dataset

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
DsTest.Clear()
WorkerON = False
End Sub
End Class
 
Last edited:
WorkerON is not necessary, BackgroundWorker has a IsBusy property. You can also make that button not Enabled when that action is not available.

DsTest.Clear() is also not necessary, the TableAdapter has a ClearBeforeFill property that defaults to True.

Since you are using strongly typed dataset and the DataGridView is bound to the BindingSource by default you can remove the "ContactDataGridView.DataSource=" call and replace it with "ContactBindingSource.ResetBindings(False)" to have the grid update with new data. If not other problems will occur, which could be solved by removing the source first "ContactDataGridView.DataSource = Nothing", but I'd prefer leaving the datasource and update the bindingsource afterwards.
 
Thank you

Thank you for your help.

This did exactly what I needed it to do. However, after I put this in my actual project, I found that I have a with "cross - threading". I tried reading in order to understand what exactly I need to do fix this, but I'm not very clear. It appears that the issue is with my text boxes.

the code that stops is

Dim Classification As String

If cbxClassification.Text = " " then
Classification = "%"
else
End If

Is there already a discussion on this where I can "read up" some?
 
Better do UI interaction before you run the background work, and from ProgressChanged/RunWorkerCompleted event handlers, that's what they were designed for. Else you have to use Control.Invoke to invoke delegate calls on UI thread.
 
Thanks JohnH! I originally thought that I was supposed to do all the UI stuff outside of the background worker.

My problem was/IS: How do I pass the info attained in UI back to the background worker.

Following is a short sample of what I think should happen, even though I'm not sure how to do it. i.e.-How do I pass the NAME

I realize that this is elementary level stuff, but I'm not a programmer by profession... and every book that I have on the subject is ... well... elementary. If anyone has a suggested reading; I'm willing to learn.

*****

Private Sub User_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim NAME As String
NAME = txtName.Text
BackgroundWorker1.WorkerReportsProgress = False
BackgroundWorker1.WorkerSupportsCancellation = False
BackgroundWorker1.RunWorkerAsync()
End Sub

Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
(Actual Work Part)--->> Me.ContactTableAdapter.Fill(Me.DsTest.Contact, Contact:= NAME)
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Me.Label1.Text = "Operation complete"
End Sub
 
Doing some reading "trying"

Hi...

So, it seems that if I want to use NAME in the background, I'll have to use the delegate / invoke... (although I have no idea what this means).

.... I'm assuming I'd have a delegate for the name like this

Private Delegate Sub setNAMEDelegate(ByVal NAME As String)

Private Sub setNAME(ByVal NAME As String)
If Me.txtNAME.InvokeRequired then
Me.txtNAME.Invoke(New setNAMEDelegate(AddressOf setNAME), NAME)
Else
Me.txtNAME.Text = NAME
End If
End Sub

Then.... in the DoWork section of the background worker, I can just call

Me.DataTableAdapter.Fillby(DataSet.Table, Name:= txtName.Text)

****

Maybe?
 
No, you'd want to pass such info before starting the background work:
VB.NET:
BackgroundWorker1.RunWorkerAsync(txtName.Text)
In DoWork:
VB.NET:
Dim name As String = CStr(e.Argument)
If name <> String.Empty Then
    'FillBy
Else
    'Fill (all)
End If
 
Back
Top