How to remove and insert rows from one virtual grid to other through drag and drop in WinForms GridControl?
Drag and drop
You can insert and remove rows when the external data sources for the two virtual grids support insertion/removal of rows. This implements the deletion of rows from the source grid and inserts them into the target grid along with special drawing queues. Since these are virtual grids where the grid does not manage the data, the sample uses a derived grid and interacts with the virtual control methods like OnDragEnter, OnDragDrop, etc., to implement the requested behavior with custom visual cues being drawn as you drag.
public class DnDGridControl : GridControl
{
public VirtDataSource virtDataSource = null;
private Point mouseDownPoint = Point.Empty;
private bool mouseDownInDrag = false;
public DnDGridControl() : base()
{
this.AllowDrop = true;
this.DataObjectConsumerOptions = Syncfusion.Windows.Forms.Grid.GridDataObjectConsumerOptions.None;
this.ControllerOptions = ((((Syncfusion.Windows.Forms.Grid.GridControllerOptions.ClickCells | Syncfusion.Windows.Forms.Grid.GridControllerOptions.DragSelectRowOrColumn)
| Syncfusion.Windows.Forms.Grid.GridControllerOptions.SelectCells)
| Syncfusion.Windows.Forms.Grid.GridControllerOptions.ExcelLikeSelection)
| Syncfusion.Windows.Forms.Grid.GridControllerOptions.ResizeCells);
}
#region controlling the cursor
protected virtual void OnQueryShowTheDragCursor(QueryShowTheDragCursorEventArgs e)
{
if(QueryShowTheDragCursor != null)
QueryShowTheDragCursor(this, e);
}
protected override void OnSetCursor(ref System.Windows.Forms.Message m)
{
if(Control.MouseButtons != MouseButtons.Left && QueryShowDndCursor())
{
Cursor.Current = DnDGridControl.CanStartDragCursor;
}
else
base.OnSetCursor(ref m);
}
protected override void OnDragDrop(System.Windows.Forms.DragEventArgs e)
{
CustomDragEventArgs ce = new CustomDragEventArgs(e);
this.OnDropCustomData(ce);
if(ce.Handled)
{
e.Effect = ce.Effect;
return;
}
if(e.Data.GetDataPresent("SelectedRowObjects"))
{
e.Effect = DragDropEffects.Move;
ArrayList data = (ArrayList)e.Data.GetData("SelectedRowObjects");
int row, col;
Point pt1 = this.PointToClient(new Point(e.X, e.Y));
this.PointToRowCol(pt1, out row, out col);
this.dropRowInThisGrid = row;
this.BeginUpdate();
for(int i = data.Count - 1; i >= 0; --i)
{
this.virtDataSource.Insert(row - 1, data[i]);
}
this.EndUpdate();
this.Refresh();
return;
}
base.OnDragDrop(e);
}
protected override void OnDragEnter(System.Windows.Forms.DragEventArgs e)
{
int row, col;
if(e.Data.GetDataPresent("Text"))
{
string s = (string)e.Data.GetData("Text");
string[] lines = s.Split('\n');
nDndRowExt = lines.GetLength(0);
nDndColExt = nDndRowExt > 0 ? lines[0].Split('\t').GetLength(0) : 1;
if(nDndRowExt > 1)
nDndRowExt--;
e.Effect = DragDropEffects.Move;
Point pt1 = this.PointToClient(new Point(e.X, e.Y));
this.PointToRowCol(pt1, out row, out col);
if(row != this.lastMarkedRow) this.UpdateTheRectangle(this.RangeInfoToRectangle(GridRangeInfo.Cells(row, this.LeftColIndex, row, this.ViewLayout.LastVisibleCol)));
}
}
protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
{
mouseDownPoint = new Point(e.X, e.Y);
this.PointToRowCol(mouseDownPoint, out this.lastMarkedRow, out this.lastMarkedCol, -1);
mouseDownInDrag = QueryShowDndCursor();
if(mouseDownInDrag)
{
// Drags with text data.
string data = CopyText();
DataObject dataObj = new DataObject(data);
CustomDataEventArgs cde = new CustomDataEventArgs(dataObj); OnSetCustomData(cde);
//gets the selected row indexes
GridRangeInfoList rangeList = this.Selections.GetSelectedRows(false, false);
ArrayList a = new ArrayList();
ArrayList dataRows = new ArrayList();
foreach(GridRangeInfo range in rangeList)
{
for(int i = range.Top; i <= range.Bottom; ++i)
{
a.Add(i-1); //-1 because zero based index in data
dataRows.Add(this.virtDataSource[i-1]);
}
}
a.Sort(); //Sorts from top to bottom for ease of deleting.
((DataObject)cde.Data).SetData("SelectedRowObjects", dataRows);
this.dropRowInThisGrid = -1;
DragDropEffects dde = this.DoDragDrop(cde.Data, DragDropEffects.Move);
if(dde == DragDropEffects.Move)
{
this.BeginUpdate();
for(int i = a.Count - 1; i >= 0; --i)
{
int offSet = (dropRowInThisGrid == -1 || dropRowInThisGrid > (int)a[i])
? 0 : a.Count - i;
this.virtDataSource.RemoveAt(offSet + (int)a[i]);
}
this.EndUpdate();
this.Refresh();
}
ResetDrag();
return;
}
base.OnMouseDown(e);
}Public Class DnDGridControl
Inherits GridControl
Public virtDataSource As VirtDataSource = Nothing
Private mouseDownPoint As Point = Point.Empty
Private mouseDownInDrag As Boolean = False
Public Sub New()
MyBase.New()
Me.AllowDrop = True
Me.DataObjectConsumerOptions = Syncfusion.Windows.Forms.Grid.GridDataObjectConsumerOptions.None
Me.ControllerOptions = ((((Syncfusion.Windows.Forms.Grid.GridControllerOptions.ClickCells Or Syncfusion.Windows.Forms.Grid.GridControllerOptions.DragSelectRowOrColumn) Or Syncfusion.Windows.Forms.Grid.GridControllerOptions.SelectCells) Or Syncfusion.Windows.Forms.Grid.GridControllerOptions.ExcelLikeSelection) Or Syncfusion.Windows.Forms.Grid.GridControllerOptions.ResizeCells)
End Sub
#Region "controlling the cursor"
Protected Overridable Sub OnQueryShowTheDragCursor(ByVal e As QueryShowTheDragCursorEventArgs)
RaiseEvent QueryShowTheDragCursor(Me, e)
End Sub
Protected Overrides Sub OnSetCursor(ByRef m As System.Windows.Forms.Message)
If Control.MouseButtons <> MouseButtons.Left AndAlso QueryShowDndCursor() Then
Cursor.Current = DnDGridControl.CanStartDragCursor
Else
MyBase.OnSetCursor(m)
End If
End Sub
Protected Overrides Sub OnDragDrop(ByVal e As System.Windows.Forms.DragEventArgs)
Dim ce As New CustomDragEventArgs(e)
Me.OnDropCustomData(ce)
If ce.Handled Then
e.Effect = ce.Effect
Return
End If
If e.Data.GetDataPresent("SelectedRowObjects") Then
e.Effect = DragDropEffects.Move
Dim data As ArrayList = CType(e.Data.GetData("SelectedRowObjects"), ArrayList)
Dim row, col As Integer
Dim pt1 As Point = Me.PointToClient(New Point(e.X, e.Y))
Me.PointToRowCol(pt1, row, col)
Me.dropRowInThisGrid = row
Me.BeginUpdate()
For i As Integer = data.Count - 1 To 0 Step -1
Me.virtDataSource.Insert(row - 1, data(i))
Next i
Me.EndUpdate()
Me.Refresh()
Return
End If
MyBase.OnDragDrop(e)
End Sub
Protected Overrides Sub OnDragEnter(ByVal e As System.Windows.Forms.DragEventArgs)
Dim row, col As Integer
If e.Data.GetDataPresent("Text") Then
Dim s As String = CStr(e.Data.GetData("Text"))
Dim lines() As String = s.Split(ControlChars.Lf)
nDndRowExt = lines.GetLength(0)
nDndColExt = If(nDndRowExt > 0, lines(0).Split(ControlChars.Tab).GetLength(0), 1)
If nDndRowExt > 1 Then
nDndRowExt -= 1
End If
e.Effect = DragDropEffects.Move
Dim pt1 As Point = Me.PointToClient(New Point(e.X, e.Y))
Me.PointToRowCol(pt1, row, col)
If row <> Me.lastMarkedRow Then Me.UpdateTheRectangle(Me.RangeInfoToRectangle(GridRangeInfo.Cells(row, Me.LeftColIndex, row, Me.ViewLayout.LastVisibleCol)))
End If
End If
End Sub
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
mouseDownPoint = New Point(e.X, e.Y)
Me.PointToRowCol(mouseDownPoint, Me.lastMarkedRow, Me.lastMarkedCol, -1)
mouseDownInDrag = QueryShowDndCursor()
If mouseDownInDrag Then
'Drags with text data
Dim data As String = CopyText()
Dim dataObj As New DataObject(data)
Dim cde As New CustomDataEventArgs(dataObj)
OnSetCustomData(cde)
'gets the selected row indexes
Dim rangeList As GridRangeInfoList = Me.Selections.GetSelectedRows(False, False)
Dim a As New ArrayList()
Dim dataRows As New ArrayList()
For Each range As GridRangeInfo In rangeList
For i As Integer = range.Top To range.Bottom
a.Add(i-1) '-1 because zero based index in data
dataRows.Add(Me.virtDataSource(i-1))
Next i
Next range
a.Sort() 'Sorts from top to bottom for ease of deleting.
CType(cde.Data, DataObject).SetData("SelectedRowObjects", dataRows)
Me.dropRowInThisGrid = -1
Dim dde As DragDropEffects = Me.DoDragDrop(cde.Data, DragDropEffects.Move)
If dde = DragDropEffects.Move Then
Me.BeginUpdate()
For i As Integer = a.Count - 1 To 0 Step -1
Dim offSet As Integer = If((dropRowInThisGrid = -1 OrElse dropRowInThisGrid > CInt(Fix(a(i)))), 0, a.Count - i)
Me.virtDataSource.RemoveAt(offSet + CInt(Fix(a(i))))
Next i
Me.EndUpdate()
Me.Refresh()
End If
ResetDrag()
Return
End If
MyBase.OnMouseDown(e)
End SubSamples:
C#: Adding_and_removing_rows_in_virtualgrid
VB: Adding_and_removing_rows_in_virtualgrid
Reference Link: Drag and Drop