Home > Net >  Datagridviewss and Threads
Datagridviewss and Threads

Time:10-30

I want to update a datagridview from a thread using VB.

I have tried two approaches so far, but clearly I am missing something. The two methods are:

If Control.invokeRequired Then
    Control.Invoke(Sub() Control.rows.add(Event*Date, Event*Details))

And I have tried:

If Control.InvokeRequired then
    Control.Invoke(New Addrow(AddressOf Form1.AddToDatatable), New Object() {Data_row})

Where

Public Delegate Sub Addrow(ByVal Data_row As DataRow)
   Public Sub AddToDatatable(ByVal Data_row As DataRow)
       Data_table.Rows.Add(Data_row)
       Daily_Log.Refresh()
   End Sub

CodePudding user response:

It appears that you have a DataTable bound to a DataGridView. In that case, you need to add the data to the DataTable. InvokeRequired and Invoke are instance members of the Control class, so need to be accessed via a control reference. If you know the code is being executed on a secondary thread then using InvokeRequired is pointless. I suspect that your code should be like this:

myDataGridView.Invoke(Sub() myDataTable.Rows.Add(someValue, someOtherValue))

Your would only need to use InvokeRequired if the code is in a method that might be executed on the UI thread or a secondary thread. For instance, you might do this:

Private Sub AddRow(column1Value As Object, column2Value As Object)
    If myDataGridView.InvokeRequired Then
        myDataGridView.Invoke(New Action(Of Object, Object)(AddressOf AddRow), column1Value, column2Value)
    Else
        myDataTable.Rows.Add(column1Value, column2Value)
    End If
End Sub

You can then just call that method anywhere and it will handle the rest. You can do this on a secondary thread:

AddRow(someValue, someOtherValue)

On that call, InvokeRequired will be True, so a delegate will be created for the same AddRow method nad passed to Invoke, along with the parameter values. Invoke will cross the thread boundary and invoke AddRow a second time. This time InvokeRequired will be False, so the row will be added to the DataTable.

CodePudding user response:

Thank you everybody for your suggestions. I wrote my question in abject frustration on Thursday after spending a day reading forums trying to find out what was going on. Friday afternoon I eventually worked it out.

Two things led to me finding a solution.

  1. I could not work out why invokerequired was always returning false. I initially assumed this was because I was running in debug to watch the code. In frustration I removed the invokerequired and let the code go to the invoke. This was the best thing I could have done even though it threw an error. Something about the form event not created

  2. This made me wonder about the form and the control so I added some debug code on isdisposed and eventcreated. Both returned false.

Yet the form was sitting in front of my eyes waiting for data...

It then occurred to me that maybe, just maybe I was not able to address the displayed form at all from the thread. In desperation I decided to add the form to the thread initiation and receive the form as a parameter when the thread initiated.

Omg! It worked. Invokerequired suddenly turned true and the invoke worked without error and data started appearing on my form, cracked it!

They say hard learning is not forgotten quickly, and I doubt I'll forget this quickly.

In summary when initiating the thread, pass the live form as the sole parameter and in your thread reference the passed form, not the from directly... Grrr. I hope me posting this helps save someone else from tearing their hair out.

  • Related