nyarlathotep
Member
- Joined
- Mar 23, 2012
- Messages
- 6
- Programming Experience
- 1-3
After much googling I've put together an 'almost' solution to dragging and dropping multiple rows from one grid to another. This is going to be a long post.:crying:
It's basically code borrowed and modified from two different webpages.
There is a class which modifies the datagridview control to create a new control I'm calling multigrid. The code is in block 1 below.
I think this line from 'Overrides OnMouseMove'
Should put the SelectedRows object into the drag data.
If make a form then add this control as multiselect1 and a datagridview as datagridview2 (with the same column settings). I think I should be able to select a bunch of rows in multiselect1 and drop them onto datagridview2 by coding as in code block 2.
Problem: It doesn't build with the Error 'Expression is of type 'System.Windows.Forms.IDataObject', which is not a collection type. Obviously the .selectedrows is a collection so clearly the compiler isn't seeing that.
Can Obi Wan help. You're my only hope.
Code Block One 'multiselect class'
Code block 2 'drag drop handling'
It's basically code borrowed and modified from two different webpages.
There is a class which modifies the datagridview control to create a new control I'm calling multigrid. The code is in block 1 below.
I think this line from 'Overrides OnMouseMove'
VB.NET:
Dim dropEffect As DragDropEffects = Me.DoDragDrop(Me.SelectedRows, DragDropEffects.Move)
Should put the SelectedRows object into the drag data.
If make a form then add this control as multiselect1 and a datagridview as datagridview2 (with the same column settings). I think I should be able to select a bunch of rows in multiselect1 and drop them onto datagridview2 by coding as in code block 2.
Problem: It doesn't build with the Error 'Expression is of type 'System.Windows.Forms.IDataObject', which is not a collection type. Obviously the .selectedrows is a collection so clearly the compiler isn't seeing that.
Can Obi Wan help. You're my only hope.
Code Block One 'multiselect class'
VB.NET:
Imports System.DrawingImports System.IO
Imports System.ComponentModel
Imports System.Reflection
Imports System.Windows.Forms
<ToolboxBitmap(GetType(multigrid), "multigridicon.bmp")>
Public Class multigrid
Inherits System.Windows.Forms.DataGridView
Public Property AllowMultiRowDrag As Boolean = False
Private dragBoxFromMouseDown As Rectangle
Private rowIndexFromMouseDown As Int32
Private lastLeftMouseDownArgs As MouseEventArgs
Protected Overrides Sub OnMouseDown(e As System.Windows.Forms.MouseEventArgs)
If (e.Button And Windows.Forms.MouseButtons.Left) = Windows.Forms.MouseButtons.Left Then
rowIndexFromMouseDown = Me.HitTest(e.X, e.Y).RowIndex
If rowIndexFromMouseDown <> -1 Then
Dim dragSize As Size = SystemInformation.DragSize
dragBoxFromMouseDown = New Rectangle(New Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize)
lastLeftMouseDownArgs = e 'remember the MouseEventArgs
If AllowMultiRowDrag Then
Exit Sub 'Don't call the base function here to keep the selection
End If
Else
dragBoxFromMouseDown = Rectangle.Empty
lastLeftMouseDownArgs = Nothing
End If
End If
MyBase.OnMouseDown(e) 'in all other cases call the base function
End Sub
Protected Overrides Sub OnMouseUp(e As System.Windows.Forms.MouseEventArgs)
If lastLeftMouseDownArgs IsNot Nothing AndAlso (e.Button And Windows.Forms.MouseButtons.Left) = Windows.Forms.MouseButtons.Left Then
'there has been a multiselect drag operation so catch up the MouseDown event
If AllowMultiRowDrag Then MyBase.OnMouseDown(lastLeftMouseDownArgs)
End If
MyBase.OnMouseUp(e) 'now call the base Up-function
End Sub
Protected Overrides Sub OnMouseMove(e As System.Windows.Forms.MouseEventArgs)
If lastLeftMouseDownArgs IsNot Nothing AndAlso (e.Button And Windows.Forms.MouseButtons.Left) = Windows.Forms.MouseButtons.Left Then
If (dragBoxFromMouseDown <> Rectangle.Empty) AndAlso (Not dragBoxFromMouseDown.Contains(e.X, e.Y)) Then
'we want to drag one/multiple rows
Dim row As DataGridViewRow = Me.Rows(rowIndexFromMouseDown)
row.Selected = True 'always select the row that was under the mouse in the OnMouseDown event.
If Me.AllowMultiRowDrag Then
'multiselect drag, so make all selected rows the drag data
Dim dropEffect As DragDropEffects = Me.DoDragDrop(Me.SelectedRows, DragDropEffects.Move)
Else
'only one row to drag
Dim dropEffect As DragDropEffects = Me.DoDragDrop(row, DragDropEffects.Move)
End If
End If
End If
MyBase.OnMouseMove(e) 'let's do the base class the rest
End Sub
End Class
Code block 2 'drag drop handling'
VB.NET:
Private Sub DataGridView2_DragOver(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles DataGridView2.DragOver 'Just to Show a mouse icon to denote drop is allowed here
e.Effect = DragDropEffects.Move
End Sub
Private Sub DataGridView2_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles DataGridView2.DragDrop
Dim oRow As DataGridViewRow
Dim oRow2 As DataGridViewRow
Try
For Each oRow In e.Data
oDataRow = DataGridView2.NewRow
CopyDataRow(oSourceDataRow, oDataRow)
Next oRow
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub CopyDataRow(ByVal oSourceRow As DataRow, ByVal oTargetRow As DataRow)
Dim nIndex As Integer = 0
Dim oItem As Object
'- Copy all the fields from the source row to the target row
For Each oItem In oSourceRow.ItemArray
oTargetRow(nIndex) = oItem
nIndex += 1
Next
End Sub