I'm trying to find a way to check for changes in a DataGridView. The gridview does not have a binding source because I am populating it based on some other information.

Right now I get a NullReferenceException. It happens as the gridview is populated. I have marked the line where this happens.

Here is what I have now...

Private Sub loadTheView
        Dim tblModels As New DataSet1.docHeaderDataTable
        Dim reader As SqlDataReader
        Dim sqlSOPDept As New SqlClient.SqlCommand
        Dim sqlConn As New SqlClient.SqlConnection("Data Source=IMS-SQL-01;Initial Catalog=ImageTraining;Integrated Security=True")
        sqlSOPDept.CommandText = "SELECT DISTINCT model, part, sop, revision FROM [ImageTraining].[dbo].[docHeader] WHERE sop LIKE '" & Convert.ToString(Me.cmbDept.SelectedValue).Replace(" ", "") & "%'"
        sqlSOPDept.CommandType = CommandType.Text
        sqlSOPDept.Connection = sqlConn
        sqlConn.Open()
        reader = sqlSOPDept.ExecuteReader
        If reader.HasRows Then
            Do While reader.Read()
                Dim rowNum As Integer = 0
                Dim rowTbl As Data.DataRow
                rowTbl = tblModels.NewRow
                rowTbl.Item("model") = reader.Item("model")
                rowTbl.Item("part") = reader.Item("part")
                rowTbl.Item("sop") = reader.Item("sop")
                rowTbl.Item("revision") = reader.Item("revision")
                tblModels.Rows.Add(rowTbl)
                rowNum += 1
            Loop
        End If
        reader.Close()


        'we have data from the reader in a table. set the DataGridView dataSource to that table.
        
        Me.DataGridView1.DataSource = tblModels
    

    End Sub


    Private Sub DataGridView1_RowEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.RowEnter
        If Me.DataGridView1.Columns(0).Equals(Nothing) Then
        Else
            Me.rwFirst = ""
            Me.rwDGV = Me.DataGridView1.CurrentRow
            'the line below this is where the error occurs. 
            Me.rwIndex = Me.DataGridView1.CurrentRow.Index
            Me.rwFirst = RowtoString(Me.rwIndex)
        End If
    End Sub

    Private Sub DataGridView1_RowLeave(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.RowLeave
        Me.rwSecond = RowtoString(rwIndex)
        If String.Compare(rwFirst, rwSecond) Then
            MsgBox("there has been a change")
        End If
    End Sub

    Function RowtoString(ByVal row As Integer) As String
        Dim z As Integer = 0
        Dim text As String
        For z = 0 To DataGridView1.ColumnCount - 1
            text = text & DataGridView1.Item(z, row).Value
        Next
        Return text
    End Function

Any help is much appreciated!

Dani AI

Generated

Short diagnosis and a few practical fixes.

The NullReferenceException is most likely caused by reading DataGridView.CurrentRow (or Columns(0)) while the grid is still being populated — CurrentRow can be Nothing and Columns may not exist yet. was on the right track: use the event-supplied row index instead of relying on CurrentRow. Also note a logic bug in the original comparison: String.Compare returns an Integer, not a Boolean — test for <> 0 (or use <> / Equals) when comparing strings.

If you want a safe row snapshot + compare approach (works even without a BindingSource), capture the row by e.RowIndex and build a normalized string while guarding against Nothing/DBNull:

' capture on RowEnter
Private Sub dgv_RowEnter(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.RowEnter
    If e.RowIndex < 0 OrElse e.RowIndex >= DataGridView1.RowCount Then Return
    currentSnapshot = SnapshotRow(e.RowIndex)
End Sub

Private Function SnapshotRow(rowIdx As Integer) As String
    Dim sb As New System.Text.StringBuilder()
    For c As Integer = 0 To DataGridView1.ColumnCount - 1
        sb.Append(Convert.ToString(DataGridView1.Item(c, rowIdx).Value))
        sb.Append("|")
    Next
    Return sb.ToString()
End Function

Better alternatives (recommended)

  • If the grid is bound to a DataTable, use the table’s change tracking: call AcceptChanges() after load and later check DataTable.GetChanges() or DataTable.HasChanges() and inspect DataRow.RowState for Modified/Added/Deleted rows. That is more reliable than string comparisons.
  • For cell-level detection, prefer CellValueChanged (and handle CurrentCellDirtyStateChanged for checkboxes) or RowValidated to ensure edits are committed before you compare.

Troubleshooting tips

  • Disable handlers while loading (or use a boolean isLoading guard) so population doesn’t trigger compare logic.
  • Always validate indices and use Convert.ToString to avoid DBNull/Null problems.
  • Commit edits with EndEdit before checking.

These notes should help avoid the NullReferenceException and give safer ways to detect edits. ’s decision to change the approach is sensible — prefer DataTable change tracking or cell/row validation events for reliability.

Recommended Answers

All 2 Replies

hmm maybe u can use

me.rwindex = e.rowindex

try this it must be your answer couse i was try.

Oneryavuz - I'm sorry it took so long for me to reply. The issue gave me enough of a problem that I have decided to just change the way it is done.

I do appreciate the reply. Thanks for the idea!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.