user4954249
user4954249

Reputation:

Null Reference Exception with DataGridView

Option Explicit On
Option Strict On

Imports System
Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Public Class Example
   Inherits System.Windows.Forms.Form

   Private listofTs As List(Of T) = New List(Of T)
   Private mouseDownPosition As Point = New Point()
   Private queue1 As New List(Of T)
   Private queue2 As New List(Of T)
   Private queue3 As New List(Of T)
   Private m_fromDataGridView As String = ""
   Private binding1 As BindingSource = New BindingSource()
   Private binding2 As BindingSource = New BindingSource()
   Private binding3 As BindingSource = New BindingSource()

  Private Sub Add(ByRef targetGrid As DataGridView, ByRef queue As List(Of T), ByRef building As BindingSource, ByRef previousGrid As DataGridView, ByRef prevQueue As As List(Of T), ByRef prevBindingSource As BindingSource)
    previousGrid.Refresh()
    previousGrid.SuspendLayout()
    For Each t As T In listofTs
        queue.Add(New T(t.String1, t.String2, t.String3, t.Int1, t.Int2))
        prevQueue.Remove(t)
    Next
    prevBindingSource.ResetBindings(False)
    previousGrid.CurrentCell = Nothing
    previousGrid.ResumeLayout(False)
    previousGrid.Refresh()
    building.ResetBindings(False)
    targetGrid.CurrentCell = targetGrid(1, targetGrid.Rows.Count - 1)
    targetGrid.Focus()
End Sub

  Private Sub Views_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles View1.MouseDown, View2.MouseDown, View3.MouseDown
    mouseDownPosition = e.Location
  End Sub

  Private Sub View1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles View1.MouseMove
    If CheckMouseMovement(sender, View1, e) Then
        CopyRowForDragAndDrop(sender, View1, e, DragDropEffects.Move)
    End If
  End Sub

  Private Sub View2_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles View2.MouseMove
    If CheckMouseMovement(sender, View2, e) Then
        CopyRowForDragAndDrop(sender, View2, e, DragDropEffects.Move)
    End If
  End Sub

  Private Sub View3_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles View2.MouseMove
    If CheckMouseMovement(sender, View3, e) Then
        CopyRowForDragAndDrop(sender, View3, e, DragDropEffects.Move)
    End If
  End Sub

  Private Sub CopyRowForDragAndDrop(ByVal sender As System.Object, ByRef dataGridView As DataGridView, ByVal e As System.Windows.Forms.MouseEventArgs, ByVal dropEffect As DragDropEffects)
    listofTs = New List(Of T)
    For Each row As DataGridViewRow In dataGridView.Rows
        If Convert.ToBoolean(row.Cells.Item(0).Value) Then
            m_fromDataGridView = dataGridView.Name
            Dim t As T = DirectCast(row.DataBoundItem, T)
            listofTs.Add(t)
        End If
    Next
    If listofTs.Count > 0 Then
        dataGridView.DoDragDrop(sender, dropEffect)
    End If
  End Sub

  Private Function CheckMouseMovement(ByVal sender As System.Object, ByRef dataGridView As DataGridView, ByVal e As System.Windows.Forms.MouseEventArgs) As Boolean
    If e.Button = MouseButtons.Left Then
        If Math.Abs(mouseDownPosition.X - e.X) >= SystemInformation.DoubleClickSize.Width Or Math.Abs(mouseDownPosition.Y - e.Y) >= SystemInformation.DoubleClickSize.Height Then
            Dim hit As Integer = dataGridView.HitTest(mouseDownPosition.X, mouseDownPosition.Y).RowIndex
            If hit >= 0 Then
                Return True
            End If
        End If
    End If
    Return False
  End Function

  Private Sub View1_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles View1.DragDrop
    DragDropIntoNewDataGrid(sender, View1, e, queue1, binding1)
  End Sub

  Private Sub View2_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles View2.DragDrop
    DragDropIntoNewDataGrid(sender, View2, e, queue2, binding2)
  End Sub

  Private Sub View3_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles View3.DragDrop
    DragDropIntoNewDataGrid(sender, View3, e, queue3, binding3)
  End Sub

  Private Sub DragDropIntoNewDataGrid(ByVal sender As System.Object, ByRef m_toDataGridView As DataGridView, ByVal e As System.Windows.Forms.DragEventArgs, ByRef queue As List(Of T), ByRef building As BindingSource)
    Dim pointToDropTo As Point = m_toDataGridView.PointToClient(New Point(e.X, e.Y))
    If m_toDataGridView.Visible Then
        If String.Compare(m_fromDataGridView, View1.Name, True) = 0 Then
            Add(m_toDataGridView, queue, building, View1, queue1, binding1)
        ElseIf String.Compare(m_fromDataGridView, View3.Name, True) = 0 Then
            Add(m_toDataGridView, queue, building, View2, queue2, binding2)
        ElseIf String.Compare(m_fromDataGridView, View3.Name, True) = 0 Then
            Add(m_toDataGridView, queue, building, View3, queue3, binding3)
        End If
    End If
  End Sub

  Private Sub Views_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles View1.DragEnter, View2.DragEnter, View3.DragEnter
    e.Effect = DragDropEffects.Move
  End Sub

  Structure T
      Dim String1 As String
      Dim String2 As String
      Dim String3 As String
      Dim Int1 As Integer
      Dim Int2 As Integer
      Public Sub New(ByVal string1 As String, ByVal string2 As String, ByVal string3 As String, ByVal int1 As Integer, ByVal int2 As Integer)
          Me.String1 = string1
          Me.String2 = string2
          Me.String3 = string3
          Me.Int1 = int1
          Me.Int2 = int2
      End Sub
  End Structure

  Public Sub New()

  End Sub
End Class

My issue is when I run the code and I check all rows to move from one datagridview to another and where the sometimes will come up with a Null Reference Exception (pointed out in a comment noting in above code) and when I look at the VS exception it states that the Index is { Index: -1 } and the dataGridViews.Item(index).DataBoundItem is empty. Sometimes the code has no problem and I have no idea what is causing it to happen sometimes but others. Does anyone have any suggestions? Since it has to go into production soon and I can't see where the issue is.

Is there a different way to get the data out then this: dataGridViewRows.Item(index).DataBoundItem?

Upvotes: 0

Views: 382

Answers (1)

user4954249
user4954249

Reputation:

I figured it out finally. Instead of keeping a list of datagridviews I switched it to a list of ts and did

listofTs = New List(Of T)
For Each row As DataGridViewRow In dataGridView.Rows
    If Convert.ToBoolean(row.Cells.Item(0).Value) Then
        m_fromDataGridView = dataGridView.Name
        Dim t As T = DirectCast(row.DataBoundItem, T)
        listofTs.Add(t)
    End If
Next

And doing this later for the add

For Each t As T In listofTs
    queue.Add(New T(t.String1, t.String2, t.String3, t.Int1, t.Int2))
    prevQueue.Remove(t)
Next

Instead of this

listofRows = New List(Of DataGridViewRow)
For Each row As DataGridViewRow In dataGridView.Rows
    If Convert.ToBoolean(row.Cells.Item(0).Value) Then
        m_fromDataGridView = dataGridView.Name
        listofRows.Add(row)
    End If
Next

And then later doing this

For Each row As T In listofRows 
    Dim t As T = DirectCast(row.DataBoundItem, T)
    queue.Add(New T(t.String1, t.String2, t.String3, t.Int1, t.Int2))
    prevQueue.Remove(t)
Next

Upvotes: 1

Related Questions