Reputation:
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
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