KB Article T949086
Visible to All Users

Drag-and-Drop - WinForms Cheat Sheet

Other DevExpress WinForms Cheat Sheets


Built-in drag-and-drop

The following DevExpress WinForms controls support inner drag-and-drop operations out of the box.

Drag-and-Drop Behavior - Drag-and-drop within and between DevExpress controls

Drag-and-Drop Behavior (part of the BehaviorManager component) allows drag-and-drop operations between and within the following controls:

The Drag-and-Drop Behavior has the following features:

  • A drag operation is initiated automatically. You do not need to handle mouse events.
  • The Behavior displays previews of dragged items.
  • Events allow you to identify data items, customize preview images, cancel operations, etc.
  • To allow a drag-and-drop between two controls (from one grid to another, from a grid to a tree list, etc.), create two Drag-and-Drop Behavior objects. Attach them to both controls.
  • If the data structure of the source and target controls differs, handle drag events to convert data items.
  • The Drag-and-Drop Behavior does not perform drag-and-drop operations if a control's Control.AllowDrop property is set to true. It is assumed that the standard .NET drag-and-drop engine will be used in this case.

The standard .NET drag-and-drop engine

If the techniques above do not suit your needs, consider using the standard drag-and-drop engine. It allows you to implement drag-and-drop operations between and within controls and applications of any complexity. See Performing a Drag-and-Drop Operation in Windows Forms for more information.

Note: To avoid conflicts, do not use the standard .NET drag-and-drop engine together with DevExpress controls' built-in drag-and-drop operations and Drag-and-Drop Behavior.

See also:


Examples

Update underlying data sources

Built-in drag-and-drop operations and Drag-and-Drop Behavior of DevExpress controls do not update underlying data sources to reflect visual changes. Handle the event that fires when a data element is dropped onto a control to update the underlying data source.

Start drag-and-drop operations when a user clicks a cell with an inplace editor

A drag-and-drop operation in grid and treelist controls is initiated when a user clicks a row. The operation is canceled if a mouse press activates an in-place cell editor because the cell editor will handle all subsequent mouse events in this case. To prevent in-place editor activation during a drag-and-drop operation, set the EditorShowMode option to Click or MouseUp.
You may wish to refer to the following links for more information:

Reorder grid rows in the Grid View (tiles in the Tile View)

To enable users to reorder rows in Data Grid, do the following:

Code Example
C#
private void Behavior_DragOver(object sender, DragOverEventArgs e) { DragOverGridEventArgs args = DragOverGridEventArgs.GetDragOverGridEventArgs(e); e.InsertType = args.InsertType; e.InsertIndicatorLocation = args.InsertIndicatorLocation; e.Action = args.Action; Cursor.Current = args.Cursor; args.Handled = true; } private void Behavior_DragDrop(object sender, DevExpress.Utils.DragDrop.DragDropEventArgs e) { GridView targetGrid = e.Target as GridView; GridView sourceGrid = e.Source as GridView; //... sourceTable.Rows.Remove(oldRow); sourceTable.Rows.InsertAt(newRow, newRowIndex); //... }

The following link contains a complete example: How to reorder grid rows by drag and drop

Drag rows between detail Views in the Data Grid

Code Example
C#
using DevExpress.Utils.DragDrop; using DevExpress.XtraGrid.Views.Grid; // gridView1.OptionsBehavior.Editable = false; gridView1.OptionsSelection.MultiSelect = true; gridControl1.DataSource = CreateDataTable(); gridControl1.ViewRegistered += GridControl1_ViewRegistered; gridControl1.ViewRemoved += GridControl1_ViewRemoved; BehaviorManager behaviorManager = new BehaviorManager(); // private void GridControl1_ViewRegistered(object sender, DevExpress.XtraGrid.ViewOperationEventArgs e) { if (e.View.IsDetailView) { behaviorManager.Attach<DragDropBehavior>(e.View, behavior => { behavior.DragDrop += Behavior_DragDrop; behavior.DragOver += Behavior_DragOver; }); } } private void GridControl1_ViewRemoved(object sender, DevExpress.XtraGrid.ViewOperationEventArgs e){ if (e.View.IsDetailView) behaviorManager.Detach<DragDropBehavior>(e.View); } private void GridControlBehavior_DragOver(object sender, DragOverEventArgs e){ DragOverGridEventArgs args = DragOverGridEventArgs.GetDragOverGridEventArgs(e); e.InsertType = args.InsertType; e.InsertIndicatorLocation = args.InsertIndicatorLocation; e.Action = args.Action; Cursor.Current = args.Cursor; args.Handled = true; } private void Behavior_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 = gridControl.GetViewAt(gridControl.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; } } // DataTable masterTable; 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; }

Drag data from the Data Grid (GridView) to the Scheduler control

Use the standard .NET drag-and-drop engine and the SchedulerControl's PrepareDragData event.

See the following link for a complete example:
How to drag appointments from GridView and drop them onto the Scheduler Control using SchedulerDragData

Drag a grid cell to ListBoxControl and vice versa

To accomplish this task, you can use our Drag-and-Drop Behavior.
To change the preview image and show only a specific cell, handle the DragDropEvents.BeginDragDrop event and modify the image.
Use the DragDropEventArgs.Location property together with GridView.CalcHitInfo in the DragDrop event handler to locate the cell. Then, use the GridView.SetRowCellValue method with the GridHitInfo.Column and GridHitInfo.RowHandle properties to set a value.

Code Example
C#
behaviorManager1.Attach<DragDropBehavior>(listBoxControl1, behavior => { behavior.Properties.AllowDrop = true; behavior.Properties.InsertIndicatorVisible = true; behavior.Properties.PreviewVisible = true; behavior.DragDrop += Behavior_DragDrop; }); behaviorManager1.Attach<DragDropBehavior>(gridView1, behavior => { behavior.Properties.AllowDrop = true; behavior.Properties.InsertIndicatorVisible = true; behavior.Properties.PreviewVisible = true; behavior.DragDrop += Behavior_DragDrop1; behavior.BeginDragDrop += Behavior_BeginDragDrop; }); ... private void Behavior_BeginDragDrop(object sender, BeginDragDropEventArgs e) { GridControl gc = GetChildAtPoint(PointToClient(MousePosition)) as GridControl; if (gc == null) return; Point gcPoint = gc.PointToClient(MousePosition); GridView currentView = gc.GetViewAt(gcPoint) as GridView; GridViewInfo viewInfo = currentView.GetViewInfo() as GridViewInfo; GridHitInfo gridHitInfo = currentView.CalcHitInfo(gcPoint); if (gridHitInfo == null) return; if (gridHitInfo.InRowCell) { GridColumnInfoArgs currentColumnInfo = viewInfo.ColumnsInfo[gridHitInfo.Column]; int currentColumnWidth = currentColumnInfo.Bounds.Width; int indicatorWidth = viewInfo.ViewRects.IndicatorWidth; Bitmap newPreview = new Bitmap(currentColumnWidth, e.PreviewImage.Height); using (Graphics graphics = Graphics.FromImage(newPreview)) graphics.DrawImage(e.PreviewImage, new Rectangle(0, 0, currentColumnWidth - indicatorWidth, e.PreviewImage.Height), new Rectangle(currentColumnInfo.Bounds.X, 0, currentColumnWidth, e.PreviewImage.Height), GraphicsUnit.Pixel); e.PreviewImage.Dispose(); e.PreviewImage = newPreview; _gridViewPoint = MousePosition; } } private Point _gridViewPoint = Point.Empty; private void Behavior_DragDrop(object sender, DragDropEventArgs e) { GridView srcView = e.Source as GridView; ListBoxControl targetControl = e.Target as ListBoxControl; GridHitInfo hitInfo = srcView.CalcHitInfo(srcView.GridControl.PointToClient(_gridViewPoint)); _gridViewPoint = Point.Empty; if (hitInfo == null) return; if (hitInfo.InRowCell) { object cellValue = srcView.GetRowCellValue(hitInfo.RowHandle, hitInfo.Column); if (cellValue != null) targetControl.Items.Add(cellValue); } } private void Behavior_DragDrop1(object sender, DragDropEventArgs e) { GridView currentView = e.Target as GridView; Point gcPoint = currentView.GridControl.PointToClient(e.Location); GridHitInfo hitInfo = currentView.CalcHitInfo(gcPoint); ListBoxControl srcControl = e.Source as ListBoxControl; if (hitInfo.InRowCell == true && srcControl != null) { GridColumn column = hitInfo.Column; int RowHandle = hitInfo.RowHandle; var data = e.Data as List<object>; var dataValue = data[0]; currentView.SetRowCellValue(RowHandle, column, dataValue); e.Handled = true; } }

Forbid drag operation for specific groups (nodes in TreeList)

To forbid drag options in specific groups (nodes), do the following:

  • Attach the Drag-and-Drop Behavior to the GridView or TreeList.
  • Handle the DragOver event to display the insert indicator and update the mouse pointer.
    In the example below, we demonstrated how to forbid drag operations for the ID group with the 1 value (for the Data Grid) or the node with the identifier equal to 1 (for the TreeList).
Code Example
C#
// Data Grid private void Behavior_DragOver(object sender, DragOverEventArgs e) { e.Default(); GridView gridView = e.Target as GridView; GridHitInfo info = gridView.CalcHitInfo(gridView.GridControl.PointToClient(e.Location)); int groupValue = 1; if((info.InGroupRow && (int)gridView.GetGroupRowValue(info.RowHandle) == groupValue) || // check group row info.InDataRow && (int)gridView.GetRowCellValue(info.RowHandle, "ID") == groupValue) { // check child rows in the ID group e.InsertIndicatorSize = new Size(0, 0); e.Action = DragDropActions.None; e.Cursor = Cursors.No; } } // TreeList private void Behavior_DragOver(object sender, DragOverEventArgs e) { e.Default(); TreeList treeList = e.Target as TreeList; var treeListNode = treeList.CalcHitInfo(treeList.PointToClient(e.Location)).Node; int nodeKeyValue = 1; if(treeListNode != null && ( ((int)treeListNode.GetValue("ID") == nodeKeyValue && e.InsertType == InsertType.AsChild) || // check parent node treeListNode.HasAsParent(treeList.FindNodeByKeyID(nodeKeyValue)))) { // check child nodes e.InsertIndicatorSize = new Size(0, 0); e.Action = DragDropActions.None; e.Cursor = Cursors.No; } } }

Help us improve this article

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.