DataGridView的空引用异常

时间:2015-10-19 14:50:54

标签: vb.net winforms 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

我的问题是当我运行代码并检查所有行以从一个datagridview移动到另一个时,有时会出现 Null Reference Exception(在上面的代码中注明的注释中指出)< / strong>当我查看VS异常时,它指出Index是{Index:-1}而dataGridViews.Item(index).DataBoundItem是空的。有时代码没有问题,我不知道是什么导致它有时会发生,而其他人。有没有人有什么建议?由于它必须很快投入生产,我无法看到问题所在。

有没有不同的方法来获取数据然后:dataGridViewRows.Item(index).DataBoundItem?

1 个答案:

答案 0 :(得分:1)

我终于明白了。我没有保留datagridviews列表,而是将其切换到ts列表并执行了

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

稍后为添加

执行此操作
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

而不是这个

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

然后再做这个

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