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?
答案 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