Question Index out of range - DataGridView

bulsatar1

New member
Joined
Dec 4, 2014
Messages
2
Programming Experience
1-3
Afternoon Everyone,
I have been battling this error for a couple of days and can't find a way to stop it. The process is a little complicated so please bare with me.

I have a form that has a datagridview with a source of a datatable default view. There is a threaded process that can change the underlying data in the datatable, then request the datagridview to refresh it's self by invoking a datagridview.refresh. The datagridview has it's cellformatting event handled to color rows a certain color based on 3 values in the cells of that row. All of this works and works well.

The problem I am running into, which is intermittent and frustrating to anchor down, is when the defaultview is filtered (effectively shrinking and changing the index values of the underlying table) I occasionally get an index out of range error or an index not found error. These come in as a global exception and do not highlight the line that was in error (so debugging has been a pain). Ultimately, I don't really care if a cell or even a whole row isn't colored correctly in that single pass because it would be picked up correctly again later. But since everything I have done to try to isolate and/or trap the error and let it continue on doesn't work, I am at a loss.

What I have tried so far:
Try Catch (doesn't catch the error)
SyncLock on the underlying table both when the thread updates the information, and when the main UI thread gets the information when accessing the CellFormatting function
Boolean wraps so the formatting won't happen if the underlying table is being changed
suspendlayout, clear filter, refresh datagridview, reapply filter, suspendlayout (screen flashes REALLY good on that)

Here is the cellformatting sub (pretty sure this is where the error is happening):
VB.NET:
Private Sub dgStatus_Cellformat(sender As Object, e As  DataGridViewCellFormattingEventArgs) Handles dgStatus.CellFormatting
            If Not isRefreshing Then
                isRefreshing = True
                'Try
                Dim onedate As Date
                Dim twodate As Date
                Dim difference As Double
                SyncLock dtStatus
                    Dim dr As DataGridViewRow = dgStatus.Rows(e.RowIndex)
                    onedate = CType(dr.Cells(dao.Reconciliation.ONEDATE).Value, Date)
                    twodate = CType(dr.Cells(dao.Reconciliation.TWODATE).Value, Date)
                    difference = dr.Cells(dao.Reconciliation.DIFFERENCE).Value
                End SyncLock
                If onedate.Date > twodate.Date And difference <> 0 Then
                    e.CellStyle.BackColor = Color.IndianRed
                ElseIf onedate.Date > twodate.Date And difference = 0 Then
                    e.CellStyle.BackColor = Color.Khaki
                Else
                    e.CellStyle.BackColor = Color.White
                End If

                'Catch ex As Exception
                '    'only used to bypass the very rare sync error
                'End Try
                isRefreshing = False
            End If

        End Sub

Thanks for any help!
 
Modifying a bound DataTable on a secondary thread is bad. You should be doing that on the UI thread. Fix that and see if the issue persists.

By the way, it's pointless to bind the DefaultView of DataTable. Just bind the DataTable itself. The data still comes from the DefaultView anyway.
 
The datatable can be updated 5-10 times a second. I tried what you suggested and it effectively locked the main thread so that wouldn't work. I think I am just going to force the dgv to not be filtered while there is a background process running which should solve the index error.

Thanks for the tip on the defaultview
 
Back
Top