Hoh
Hoh

Reputation: 1184

Filling DataGridView from BackgroundWorker

This is the case:
I have a DataGridView in form and when I start the form DGV should start filling with BackgroundWorker.

Private Sub FirstSub()
    adoconn()
    Me.Enabled = False
    bw.RunWorkerAsync()
    Me.Enabled = True
End Sub

Private Sub bw_DoWork(sender As Object, e As DoWorkEventArgs) Handles bw.DoWork

    Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
    If DataGridView1.InvokeRequired Then
        '//For VB 10 you can use an anonymous sub
        DataGridView1.Invoke(Sub() bw_DoWork(sender, e))
    Else


        Try
            DataBaseLayer.FillDTwithSP("ArticlesSelect", ds_Tables.Articles)
            Me.DataGridView1.DataSource = ds_Tables.Articles
            Me.DataGridView1.ClearSelection()

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End If

End Sub

After Carlos giving me an example of what should I do, I did this, but now I have a problem that when I place BrakePoint is doesn't even get into bw_DoWork sub

Private Sub FirstSub()
    adoconn()
    Me.Enabled = False
    bw.WorkerReportsProgress = True
    AddHandler bw.DoWork, AddressOf bw_DoWork
    AddHandler bw.ProgressChanged, AddressOf bw_ProgressChanged
    Me.Enabled = True
End Sub
Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
    Try
        DataBaseLayer.FillDTwithSP("ArticlesSelect", ds_Tables.Articles)
            Me.DataGridView1.DataSource = ds_Tables.Articles
            Me.DataGridView1.ClearSelection()
    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub
Private Sub bw_DoWork(sender As Object, e As DoWorkEventArgs)
    Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
    bw.ReportProgress(sender, e)
End Sub

So, my desired thing is to disable all controls on form until my DataTable is filled and DataGridView is showing a result set from DT. The thing is that when I load this form it freeze and un-freeze again when everything is done, so there is no effect of BackgroundWorker at all.

If you need any more info or code parts feel free to tell me so I can solve this problem.

Thanks,
Hoh

Upvotes: 0

Views: 8166

Answers (2)

Trevor
Trevor

Reputation: 8004

After reviewing some of the details of this thread I can point out a few things I see.

  1. You are trying to set your source in ProgressChanged Event, no need if you have a delegate and use it properly.
  2. The Progress Changed Event should only be used to report progress, not change UI or any controls.
  3. No need to add handlers as they are already taken care of.

I am not sure where your calling FirstSub method, I would assume from a load event or click event perhaps, that doesn't matter anyways. Below are changes that I made and should be good for you. You can also check out my other answer's here and here, both are great for you to reference and see what need's to take place.

 Delegate Sub SetDataTable(ByVal dt As DataTable) 'Your delegate..

 Private Sub FirstSub()
    adoconn()
    Me.Enabled = False
    bw.RunWorkerAsync()
    Me.Enabled = True
 End Sub

 'The method that fills DataGridView1
 Private Sub AddSource(ByVal dt As DataTable)
    If Me.DataGridView1.InvokeRequired Then 'Invoke if required...
        Dim d As New SetDataTable(AddressOf AddSource) 
        Me.Invoke(d, New Object() {dt})
    Else 'Otherwise, no invoke required...
        Me.DataGridView1.DataSource = dt
        Me.DataGridView1.ClearSelection()
    End If
 End Sub

 Private Sub bw_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bw.DoWork
    If Not (bw.CancellationPending) Then
        DataBaseLayer.FillDTwithSP("ArticlesSelect", ds_Tables.Articles)
        AddSource(ds_Tables.Articles)
    ElseIf (bw.CancellationPending) Then
        e.Cancel = True
    End If
 End Sub

Let me know how this works out for you and check the other two links I gave you. Also on another note you could change the call in the DoWork to your method AddSource to not pass the DataTable and just call it...

MrCodexer

Upvotes: 2

Carlos Landeras
Carlos Landeras

Reputation: 11063

You should use the Event ProgressChanged, that executes the code in the UI thread, so you can safely update your controls:

_backgroundWorker.ProgressChanged += New ProgressChangedEventHandler(backgroundWorker_ProgressChanged)

Inside the Do_Work, invoke the progress like that:

 //param is the value you need to update your controls
  _backgroundWorker.ReportProgress(p, param)

  Private Sub backgroundWorker_ProgressChanged(sender As Object, e As    ProgressChangedEventArgs)

       ' Update the UI here         
  End Sub

No need to use InvokeRequired insode the ProgressChanged event.

Upvotes: 0

Related Questions