Back to Devexpress

Drag-and-Drop Grid Rows

windowsforms-401989-controls-and-libraries-data-grid-drag-and-drop.md

latest35.3 KB
Original Source

Drag-and-Drop Grid Rows

  • May 01, 2025
  • 16 minutes to read

Users can drag and drop data items (rows, tiles, etc.) in the GridControl to move them from one position to another. They can also move data items from the grid to another control.

Enable drag-and-drop operations in one of the following ways:

Note

  • DevExpress drag-and-drop implementations do not use the standard .NET drag-and-drop engine. These approaches cannot be used together.

  • DevExpress implementations of drag-and-drop include built-in control capabilities, and a separate Drag-and-Drop Behavior.

  • Drag-and-drop activates when a user clicks a row. If there is a cell editor beneath the mouse pointer, it intercepts mouse events and cancels the drag-and-drop operation. To prevent this from happening, you can set the EditorShowMode to a value different from “Default” or “MouseDown”. Otherwise, use the Row Indicator to drag rows.

Drag-and-Drop Behavior

To allow users to move data items between two controls (from one GridControl to another, from the GridControl to the TreeList or ListBoxControl), attach the Behavior to both controls. If both grids/tree lists contain the same data fields, there are no more actions required. If the data structure differs, handle the Behavior’s drag events to convert data items. See the following help topic for more information: Drag-and-Drop Behavior.

Reorder Grid Rows and Tiles

Attach the Drag-and-Drop Behavior to the GridView or TileView.

The GridView supports the following drag-and-drop operations out of the box:

  • Move selected rows to another Grid control.
  • Reorder selected rows within the GridView (supported data sources: IList, DataTable, DataView).

Important

Drag and drop does not work with sorted/filtered Data Views.

Use the GridView.OptionsDragDrop property to configure drag-and-drop operations that users can perform within the GridView.

Run Demo

You can also handle the following events to control drag-drop operations as needed:

View Example: How to handle drag-drop events

Drag Rows Between Detail Views

To allow users to move child rows between detail views in the GridControl, do the following:

  • Attach the Behavior to the master view in the Visual Studio Designer or in code.
  • Use the ViewRegistered event to attach the Behavior to the detail view. To detach the Behavior, use the ViewRemoved event.
  • Handle the DragDrop event of the Behavior attached to the master view to move the processed child row from the source detail view to the target detail view.

In this example, the Behavior Manager is placed on the component tray and the Drag-and-Drop Behavior is attached to the main view in the Visual Studio Designer.

csharp
using DevExpress.Utils.DragDrop;
using DevExpress.XtraGrid.Views.Grid;

gridView1.OptionsBehavior.Editable = false;
gridView1.OptionsSelection.MultiSelect = true;
gridControl1.DataSource = CreateDataTable();
gridControl1.ViewRegistered += GridControl1_ViewRegistered;

private void dragDropEvents1_DragDrop(object sender, DragDropEventArgs e) {
    GridView masterView = e.Source as GridView;
    // Cast the event arguments to the DragDropGridEventArgs type
    // or call the static (Shared in VB) DragDropGridEventArgs.GetDragDropGridEventArgs method
    // to get grid-specific event arguments.
    DragDropGridEventArgs realArgs = (DragDropGridEventArgs)e;
    GridView sourceView = realArgs.Source as GridView;
    GridView targetView = realArgs.Target as GridView;

    var view1 = gridControl1.GetViewAt(gridControl1.PointToClient(e.Location));
    if(sourceView != null && targetView != null) {
        // Get the processed child row's parent ID.
        var newParentId = masterView.GetRowCellValue(targetView.SourceRowHandle, "Id");
        foreach(DataRowView dataRow in realArgs.DataRows) {
            // Update the processed child row's parent ID.
            dataRow.Row["ParentId"] = newParentId;
        }
        e.Handled = true;
    }
}

private void GridControl1_ViewRegistered(object sender, DevExpress.XtraGrid.ViewOperationEventArgs e) {
    if(e.View.IsDetailView) {
        // It is assumed that the Behavior Manager is placed
        // to the component tray in the Visual Studio Designer.
        behaviorManager1.Attach<DragDropBehavior>(e.View);
    }
}

public DataTable CreateDataTable() {
    masterTable = new DataTable();
    masterTable.Columns.Add("Id", typeof(int));
    masterTable.Columns.Add("Name");
    masterTable.Columns.Add("IsActive", typeof(bool));
    masterTable.Columns.Add("OrderCount", typeof(int));
    masterTable.Columns.Add("RegistrationDate", typeof(DateTime));

    for(int i = 0; i < 10; i++) {
        masterTable.Rows.Add(i, "Name" + i, i % 2 == 0, i * 10, DateTime.Now.AddDays(i));
    }

    DataTable childTable = new DataTable();
    childTable.Columns.Add("ParentId", typeof(int));
    childTable.Columns.Add("Id", typeof(int));
    childTable.Columns.Add("Name");

    for(int i = 0; i < 20; i++) {
        childTable.Rows.Add(i % 10, i, "Name" + i);
    }

    DataSet set = new DataSet();
    set.Tables.Add(masterTable);
    set.Tables.Add(childTable);
    set.Relations.Add(masterTable.Columns["Id"], childTable.Columns["ParentId"]);

    return masterTable;
}
vb
Imports DevExpress.Utils.DragDrop
Imports DevExpress.XtraGrid.Views.Grid

gridView1.OptionsBehavior.Editable = False
gridView1.OptionsSelection.MultiSelect = True
gridControl1.DataSource = CreateDataTable()
AddHandler gridControl1.ViewRegistered, AddressOf GridControl1_ViewRegistered

Private Sub dragDropEvents1_DragDrop(ByVal sender As Object, ByVal e As DragDropEventArgs) Handles dragDropEvents1.DragDrop
    ' Cast the event arguments to the DragDropGridEventArgs type
    ' or call the static (Shared in VB) DragDropGridEventArgs.GetDragDropGridEventArgs method
    ' to get grid-specific event arguments.
    Dim masterView As GridView = TryCast(e.Source, GridView)
    Dim realArgs As DragDropGridEventArgs = CType(e, DragDropGridEventArgs)
    Dim sourceView As GridView = TryCast(realArgs.Source, GridView)
    Dim targetView As GridView = TryCast(realArgs.Target, GridView)

    Dim view1 = gridControl1.GetViewAt(gridControl1.PointToClient(e.Location))
    If sourceView IsNot Nothing AndAlso targetView IsNot Nothing Then
        ' Get the processed child row's parent ID.
        Dim newParentId = masterView.GetRowCellValue(targetView.SourceRowHandle, "Id")
        For Each dataRow As DataRowView In realArgs.DataRows
            ' Update the processed child row's parent ID.
            dataRow.Row("ParentId") = newParentId
        Next dataRow
        e.Handled = True
    End If
End Sub

Private Sub GridControl1_ViewRegistered(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.ViewOperationEventArgs)
    If e.View.IsDetailView Then
        ' It is assumed that the Behavior Manager is placed
        ' to the component tray in the Visual Studio Designer.
        behaviorManager1.Attach(Of DragDropBehavior)(e.View)
    End If
End Sub

Public Function CreateDataTable() As DataTable
    masterTable = New DataTable()
    masterTable.Columns.Add("Id", GetType(Integer))
    masterTable.Columns.Add("Name")
    masterTable.Columns.Add("IsActive", GetType(Boolean))
    masterTable.Columns.Add("OrderCount", GetType(Integer))
    masterTable.Columns.Add("RegistrationDate", GetType(Date))
    For i As Integer = 0 To 9
        masterTable.Rows.Add(i, "Name" & i, i Mod 2 = 0, i * 10, Date.Now.AddDays(i))
    Next i

    Dim childTable As New DataTable()
    childTable.Columns.Add("ParentId", GetType(Integer))
    childTable.Columns.Add("Id", GetType(Integer))
    childTable.Columns.Add("Name")

    For i As Integer = 0 To 19
        childTable.Rows.Add(i Mod 10, i, "Name" & i)
    Next i

    Dim dataSet As New DataSet()
    dataSet.Tables.Add(masterTable)
    dataSet.Tables.Add(childTable)
    dataSet.Relations.Add(masterTable.Columns("Id"), childTable.Columns("ParentId"))

    Return masterTable
End Function

Built-In Drag-and-Drop Engine in Tile View

Enable the AllowDrag option to support drag-and-drop operations within the TileView.

To access options that specify drag-and-drop operations, use the TileView.OptionsDragDrop property. For example, you can disable the ShowDropIndicators option to hide indicators that show where a tile will be inserted.

csharp
tileView1.OptionsDragDrop.AllowDrag = true;
tileView1.OptionsDragDrop.ShowDropIndicators = false;
vb
tileView1.OptionsDragDrop.AllowDrag = True
tileView1.OptionsDragDrop.ShowDropIndicators = False

The Kanban Board arranges tiles into groups (see Groups). You can use the following options to enable drag-and-drop operations within and between tile groups:

  • AllowItemDrag — Gets or sets whether to disable tile drag-and-drop operations within and from the current group.
  • DropTargetGroups — The collection of groups that can accept tiles from the current group during drag-and-drop operations.

Customize Drag-and-Drop Operations

Use the TileView‘s following events to customize drag-and-drop operations:

  • BeforeItemDrag — Fires when a drag operation is about to be started. In an event handler, you can specify the dragged tile image or cancel the operation.
  • ItemDrag — Fires repeatedly when a user drags a tile. In an event handler, you can prevent a tile from being dropped at a specific position.
  • BeforeItemDrop — Fires before a tile is dropped.
  • ItemDrop — Fires when a tile is dropped.

The code below cancels drag operations if a user starts to drag a specific tile.

csharp
private void tileView1_BeforeItemDrag(object sender, BeforeItemDragEventArgs e) {
    DevExpress.XtraGrid.Views.Tile.TileView tileView = sender as Views.Tile.TileView;
    bool sold = (int)tileView.GetRowCellValue(e.RowHandle, tileView.Columns["Status"]) == 1;
    if (sold)
        e.Cancel = true;
}
vb
Private Sub tileView1_BeforeItemDrag(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.Views.Tile.BeforeItemDragEventArgs)
    Dim tileView As DevExpress.XtraGrid.Views.Tile.TileView = TryCast(sender, DevExpress.XtraGrid.Views.Tile.TileView)
    Dim sold As Boolean = CInt(tileView.GetRowCellValue(e.RowHandle, tileView.Columns("Status"))) = 1
    If sold Then e.Cancel = True
End Sub

Standard .NET Drag-and-Drop Engine

To implement drag-and-drop operations between the GridControl and any other control, use the standard .NET drag-and-drop engine. See the DoDragDrop method for more information.

Reorder Grid Rows

To enable drag-and-drop operations within the GridControl, do the following:

  • Handle the MouseDown event to obtain the clicked row.
  • Handle the MouseMove event and call the DoDragDrop method to initiate a drag operation.
  • Handle the DragOver event to update the mouse pointer based on its location within the grid.
  • Handle the DragDrop event to move the dragged row.

View Example

The example’s 17.2.4+ branch uses the Drag-and-Drop Behavior. Checkout the 13.1.4+ branch to see the example that uses the standard .NET engine (to do this, you can call git checkout 13.1.4+ in Git Bash).

csharp
GridHitInfo downHitInfo = null;

private void gridView1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) {
    GridView view = sender as GridView;
    downHitInfo = null;

    GridHitInfo hitInfo = view.CalcHitInfo(new Point(e.X, e.Y));
    if ( Control.ModifierKeys != Keys.None )
        return;
    if ( e.Button == MouseButtons.Left && hitInfo.InRow && hitInfo.RowHandle != GridControl.NewItemRowHandle )
        downHitInfo = hitInfo;
}

private void gridView1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) {
    GridView view = sender as GridView;
    if ( e.Button == MouseButtons.Left && downHitInfo != null ) {
        Size dragSize = SystemInformation.DragSize;
        Rectangle dragRect = new Rectangle(new Point(downHitInfo.HitPoint.X - dragSize.Width / 2,
            downHitInfo.HitPoint.Y - dragSize.Height / 2), dragSize);

        if ( !dragRect.Contains(new Point(e.X, e.Y)) ) {
            view.GridControl.DoDragDrop(downHitInfo, DragDropEffects.All);
            downHitInfo = null;
        }
    }
}

private void gridControl1_DragOver(object sender, DragEventArgs e) {
    if ( e.Data.GetDataPresent(typeof(GridHitInfo)) ) {
        GridHitInfo downHitInfo = e.Data.GetData(typeof(GridHitInfo)) as GridHitInfo;
        if ( downHitInfo == null )
            return;

        GridControl grid = sender as GridControl;
        GridView view = grid.MainView as GridView;
        GridHitInfo hitInfo = view.CalcHitInfo(grid.PointToClient(new Point(e.X, e.Y)));
        if ( hitInfo.InRow && hitInfo.RowHandle != downHitInfo.RowHandle && hitInfo.RowHandle != GridControl.NewItemRowHandle )
            e.Effect = DragDropEffects.Move;
        else
            e.Effect = DragDropEffects.None;
    }
}

private void gridControl1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) {
    GridControl grid = sender as GridControl;
    GridView view = grid.MainView as GridView;
    GridHitInfo srcHitInfo = e.Data.GetData(typeof(GridHitInfo)) as GridHitInfo;
    GridHitInfo hitInfo = view.CalcHitInfo(grid.PointToClient(new Point(e.X, e.Y)));
    int sourceRow = srcHitInfo.RowHandle;
    int targetRow = hitInfo.RowHandle;
    MoveRow(sourceRow, targetRow);
}

private void MoveRow(int sourceRow, int targetRow) {
    if ( sourceRow == targetRow || sourceRow == targetRow + 1 )
        return;

    GridView view = gridView1;
    DataRow row1 = view.GetDataRow(targetRow);
    DataRow row2 = view.GetDataRow(targetRow + 1);
    DataRow dragRow = view.GetDataRow(sourceRow);
    decimal val1 = (decimal)row1[OrderFieldName];
    if ( row2 == null )
        dragRow[OrderFieldName] = val1 + 1;
    else {
        decimal val2 = (decimal)row2[OrderFieldName];
        dragRow[OrderFieldName] = (val1 + val2) / 2;
    }
}
vb
Private downHitInfo As GridHitInfo = Nothing

Private Sub gridView1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles gridView1.MouseDown
    Dim view As GridView = TryCast(sender, GridView)
    downHitInfo = Nothing

    Dim hitInfo As GridHitInfo = view.CalcHitInfo(New Point(e.X, e.Y))
    If Control.ModifierKeys <> Keys.None Then
        Return
    End If
    If e.Button = MouseButtons.Left AndAlso hitInfo.InRow AndAlso hitInfo.RowHandle <> GridControl.NewItemRowHandle Then
        downHitInfo = hitInfo
    End If
End Sub

Private Sub gridView1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles gridView1.MouseMove
    Dim view As GridView = TryCast(sender, GridView)
    If e.Button = MouseButtons.Left AndAlso downHitInfo IsNot Nothing Then
        Dim dragSize As Size = SystemInformation.DragSize
        Dim dragRect As New Rectangle(New Point(downHitInfo.HitPoint.X - dragSize.Width \ 2, downHitInfo.HitPoint.Y - dragSize.Height \ 2), dragSize)

        If (Not dragRect.Contains(New Point(e.X, e.Y))) Then
            view.GridControl.DoDragDrop(downHitInfo, DragDropEffects.All)
            downHitInfo = Nothing
        End If
    End If
End Sub

Private Sub gridControl1_DragOver(ByVal sender As Object, ByVal e As DragEventArgs) Handles gridControl1.DragOver
    If e.Data.GetDataPresent(GetType(GridHitInfo)) Then
        Dim downHitInfo As GridHitInfo = TryCast(e.Data.GetData(GetType(GridHitInfo)), GridHitInfo)
        If downHitInfo Is Nothing Then
            Return
        End If

        Dim grid As GridControl = TryCast(sender, GridControl)
        Dim view As GridView = TryCast(grid.MainView, GridView)
        Dim hitInfo As GridHitInfo = view.CalcHitInfo(grid.PointToClient(New Point(e.X, e.Y)))
        If hitInfo.InRow AndAlso hitInfo.RowHandle <> downHitInfo.RowHandle AndAlso hitInfo.RowHandle <> GridControl.NewItemRowHandle Then
            e.Effect = DragDropEffects.Move
        Else
            e.Effect = DragDropEffects.None
        End If
    End If
End Sub

Private Sub gridControl1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles gridControl1.DragDrop
    Dim grid As GridControl = TryCast(sender, GridControl)
    Dim view As GridView = TryCast(grid.MainView, GridView)
    Dim srcHitInfo As GridHitInfo = TryCast(e.Data.GetData(GetType(GridHitInfo)), GridHitInfo)
    Dim hitInfo As GridHitInfo = view.CalcHitInfo(grid.PointToClient(New Point(e.X, e.Y)))
    Dim sourceRow As Integer = srcHitInfo.RowHandle
    Dim targetRow As Integer = hitInfo.RowHandle
    MoveRow(sourceRow, targetRow)
End Sub

Private Sub MoveRow(ByVal sourceRow As Integer, ByVal targetRow As Integer)
    If sourceRow = targetRow OrElse sourceRow = targetRow + 1 Then
        Return
    End If

    Dim view As GridView = gridView1
    Dim row1 As DataRow = view.GetDataRow(targetRow)
    Dim row2 As DataRow = view.GetDataRow(targetRow + 1)
    Dim dragRow As DataRow = view.GetDataRow(sourceRow)
    Dim val1 As Decimal = CDec(row1(OrderFieldName))
    If row2 Is Nothing Then
        dragRow(OrderFieldName) = val1 + 1
    Else
        Dim val2 As Decimal = CDec(row2(OrderFieldName))
        dragRow(OrderFieldName) = (val1 + val2) / 2
    End If
End Sub

Drag Data from Grid to Scheduler

You can enable users to drag data from the GridControl to the SchedulerControl and create appointments based on that dragged data.

View Example

The example below shows how to create an application that allows users to drag a data row from a data grid to a scheduler. Users can also drag data from/to another application. The application automatically creates a new appointment based on the dragged data.

The code below handles the following events:

  • The grid view’s MouseDown event — the event handler retrieves the clicked visual element. If the user clicks a row, a GridHitInfo object that contains information about this row is assigned to a property on the form for later use.

  • The grid view’s MouseMove event — the event handler calls the grid control’s DoDragDrop to initiate a drag-and-drop operation if the left mouse button is not released within the DragSize rectangle.

  • The scheduler’s PrepareDragData event — the event handler creates a SchedulerDragData object that contains new appointments created based on the IDataObject instance received from the source control.

  • The scheduler’s AppointmentDrop event — the event handler displays confirmation.

See the following help topic for more information: Drag-and-Drop Operations in Scheduler.

csharp
using DevExpress.XtraScheduler;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;

GridHitInfo DownHitInfo { get; set; }

void OnGridViewTasksMouseDown(object sender, MouseEventArgs e) {
    GridView view = sender as GridView;
    this.DownHitInfo = null;

    GridHitInfo hitInfo = view.CalcHitInfo(new Point(e.X, e.Y));
    if (Control.ModifierKeys != Keys.None)
        return;
    if (e.Button == MouseButtons.Left && hitInfo.InRow && hitInfo.HitTest != GridHitTest.RowIndicator)
        this.DownHitInfo = hitInfo;
}

void OnGridViewTasksMouseMove(object sender, MouseEventArgs e) {
    GridView view = sender as GridView;
    if (e.Button == MouseButtons.Left && this.DownHitInfo != null) {
        Size dragSize = SystemInformation.DragSize;
        Rectangle dragRect = new Rectangle(new Point(this.DownHitInfo.HitPoint.X - dragSize.Width / 2,
            this.DownHitInfo.HitPoint.Y - dragSize.Height / 2), dragSize);

        if (!dragRect.Contains(new Point(e.X, e.Y))) {
            view.GridControl.DoDragDrop(GetDragData(view), DragDropEffects.All);
            this.DownHitInfo = null;
        }
    }
}

IDataObject GetDragData(GridView view) {
    int[] selection = view.GetSelectedRows();
    if (selection == null)
        return null;

    List<AppointmentExchangeData> exchangeList = new List<AppointmentExchangeData>();
    int count = selection.Length;
    for (int i = 0; i < count; i++) {
        int rowIndex = selection[i];
        exchangeList.Add(new AppointmentExchangeData() {
            Subject = (string)view.GetRowCellValue(rowIndex, "Subject"),
            LabelKey = (int)view.GetRowCellValue(rowIndex, "Severity"),
            StatusKey = (int)view.GetRowCellValue(rowIndex, "Priority"),
            Start = DateTime.MinValue,
            Duration = TimeSpan.FromHours((int)view.GetRowCellValue(rowIndex, "Duration")),
            Description = (string)view.GetRowCellValue(rowIndex, "Description"),
        });
    }

    return new DataObject(DataFormats.Serializable, exchangeList);
}

void OnSchedulerControlPrepareDragData(object sender, PrepareDragDataEventArgs e) {
    object data = e.DataObject.GetData(DataFormats.Serializable);
    AppointmentBaseCollection appointments = new AppointmentBaseCollection();
    foreach (AppointmentExchangeData item in (IList)data) {
        var apt = this.schedulerStorage.CreateAppointment(AppointmentType.Normal);
        apt.Subject = item.Subject;
        apt.Description = item.Description;
        apt.Start = item.Start;
        apt.Duration = item.Duration;
        apt.LabelKey = item.LabelKey;
        apt.StatusKey = item.StatusKey;
        appointments.Add(apt);
    }
    SchedulerDragData schedulerDragData = new SchedulerDragData(appointments);
    e.DragData = schedulerDragData;
}

void OnSchedulerControlAppointmentDrop(object sender, AppointmentDragEventArgs e) {
    string createEventMsg = "Creating an event at {0} on {1}.";
    string moveEventMsg = "Moving the event from {0} on {1} to {2} on {3}.";

    DateTime srcStart = e.SourceAppointment.Start;
    DateTime newStart = e.EditedAppointment.Start;

    string msg = (srcStart == DateTime.MinValue) ? String.Format(createEventMsg, newStart.ToShortTimeString(), newStart.ToShortDateString()) :
        String.Format(moveEventMsg, srcStart.ToShortTimeString(), srcStart.ToShortDateString(), newStart.ToShortTimeString(), newStart.ToShortDateString());

    if (XtraMessageBox.Show(msg + "\r\nProceed?", Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) {
        e.Allow = false;
    }
}
vb
Imports DevExpress.XtraScheduler
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraGrid.Views.Grid.ViewInfo

Private Property DownHitInfo() As GridHitInfo

Private Sub OnGridViewTasksMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles gridViewTasks.MouseDown
    Dim view As GridView = TryCast(sender, GridView)
    Me.DownHitInfo = Nothing

    Dim hitInfo As GridHitInfo = view.CalcHitInfo(New Point(e.X, e.Y))
    If Control.ModifierKeys <> Keys.None Then
        Return
    End If
    If e.Button = MouseButtons.Left AndAlso hitInfo.InRow AndAlso hitInfo.HitTest <> GridHitTest.RowIndicator Then
        Me.DownHitInfo = hitInfo
    End If
End Sub

Private Sub OnGridViewTasksMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles gridViewTasks.MouseMove
    Dim view As GridView = TryCast(sender, GridView)
    If e.Button = MouseButtons.Left AndAlso Me.DownHitInfo IsNot Nothing Then
        Dim dragSize As Size = SystemInformation.DragSize
        Dim dragRect As New Rectangle(New Point(Me.DownHitInfo.HitPoint.X - dragSize.Width \ 2, Me.DownHitInfo.HitPoint.Y - dragSize.Height \ 2), dragSize)

        If Not dragRect.Contains(New Point(e.X, e.Y)) Then
            view.GridControl.DoDragDrop(GetDragData(view), DragDropEffects.All)
            Me.DownHitInfo = Nothing
        End If
    End If
End Sub

Private Function GetDragData(ByVal view As GridView) As IDataObject
    Dim selection() As Integer = view.GetSelectedRows()
    If selection Is Nothing Then
        Return Nothing
    End If

    Dim exchangeList As New List(Of AppointmentExchangeData)()
    Dim count As Integer = selection.Length
    For i As Integer = 0 To count - 1
        Dim rowIndex As Integer = selection(i)
        exchangeList.Add(New AppointmentExchangeData() With {
            .Subject = CStr(view.GetRowCellValue(rowIndex, "Subject")),
            .LabelKey = CInt(Math.Truncate(view.GetRowCellValue(rowIndex, "Severity"))),
            .StatusKey = CInt(Math.Truncate(view.GetRowCellValue(rowIndex, "Priority"))),
            .Start = Date.MinValue,
            .Duration = TimeSpan.FromHours(CInt(Math.Truncate(view.GetRowCellValue(rowIndex, "Duration")))),
            .Description = CStr(view.GetRowCellValue(rowIndex, "Description"))
        })
    Next i

    Return New DataObject(DataFormats.Serializable, exchangeList)
End Function

Private Sub OnSchedulerControlPrepareDragData(ByVal sender As Object, ByVal e As PrepareDragDataEventArgs) Handles schedulerControl.PrepareDragData
    Dim data As Object = e.DataObject.GetData(DataFormats.Serializable)
    Dim appointments As New AppointmentBaseCollection()
    For Each item As AppointmentExchangeData In DirectCast(data, IList)
        Dim apt = Me.schedulerStorage.CreateAppointment(AppointmentType.Normal)
        apt.Subject = item.Subject
        apt.Description = item.Description
        apt.Start = item.Start
        apt.Duration = item.Duration
        apt.LabelKey = item.LabelKey
        apt.StatusKey = item.StatusKey
        appointments.Add(apt)
    Next item
    Dim schedulerDragData As New SchedulerDragData(appointments)
    e.DragData = schedulerDragData
End Sub

Private Sub OnSchedulerControlAppointmentDrop(ByVal sender As Object, ByVal e As AppointmentDragEventArgs) Handles schedulerControl.AppointmentDrop
    Dim createEventMsg As String = "Creating an event at {0} on {1}."
    Dim moveEventMsg As String = "Moving the event from {0} on {1} to {2} on {3}."

    Dim srcStart As Date = e.SourceAppointment.Start
    Dim newStart As Date = e.EditedAppointment.Start

    Dim msg As String = If(srcStart = Date.MinValue, String.Format(createEventMsg, newStart.ToShortTimeString(), newStart.ToShortDateString()), String.Format(moveEventMsg, srcStart.ToShortTimeString(), srcStart.ToShortDateString(), newStart.ToShortTimeString(), newStart.ToShortDateString()))

    If XtraMessageBox.Show(msg & vbCrLf & "Proceed?", Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.No Then
        e.Allow = False
    End If
End Sub

Drag Data from Scheduler to Grid

You can enable users to drag appointments from a SchedulerControl to GridControl and create grid rows based on the dragged appointments.

The code below handles the following events:

  • The data grid’s DragEnter event — the event handler notifies a user that they can drop data.

  • The data grid’s DragDrop event — the event handler creates grid rows based on the dragged appointment.

  • C#

  • VB.NET

csharp
using DevExpress.XtraGrid;
using DevExpress.XtraScheduler;
using System.Data;

gridControl1.AllowDrop = true;
gridControl1.DragDrop += GridControl1_DragDrop;
gridControl1.DragEnter += GridControl1_DragEnter;

private void GridControl1_DragEnter(object sender, System.Windows.Forms.DragEventArgs e) {
    e.Effect = System.Windows.Forms.DragDropEffects.All;
}
private void GridControl1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) {
    GridControl gridControl = sender as GridControl;
    SchedulerDragData data = e.Data.GetData(typeof(SchedulerDragData)) as SchedulerDragData;
    if (data != null) {
        foreach (var apt in data.Appointments) {
            var row = apt.GetRow(schedulerControl.DataStorage) as DataRowView;
            gridDataTable.Rows.Add(row.Row.ItemArray);
        }
    }
}
vb
Imports DevExpress.XtraGrid
Imports DevExpress.XtraScheduler
Imports System.Data

gridControl1.AllowDrop = True
AddHandler gridControl1.DragDrop, AddressOf GridControl1_DragDrop
AddHandler gridControl1.DragEnter, AddressOf GridControl1_DragEnter

Private Sub GridControl1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs)
    e.Effect = System.Windows.Forms.DragDropEffects.All
End Sub

Private Sub GridControl1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs)
    Dim gridControl As GridControl = TryCast(sender, GridControl)
    Dim data As SchedulerDragData = TryCast(e.Data.GetData(GetType(SchedulerDragData)), SchedulerDragData)

    If data IsNot Nothing Then
        For Each apt In data.Appointments
            Dim row = TryCast(apt.GetRow(schedulerControl.DataStorage), DataRowView)
            gridDataTable.Rows.Add(row.Row.ItemArray)
        Next
    End If
End Sub

Examples

Auto-scroll the Grid During Drag-and-Drop

This example scrolls the grid (rows and columns) vertically and horizontally when an object is dragged near the edge of the grid.

View Example

Move Selected Rows between Groups using Drag-and-Drop

This example uses Drag-and-Drop Behavior.

View Example

Cheat Sheets and Best Practices

Read the following quick-reference guide for general information and examples:

How to Drag-and-Drop Within/Between UI Controls