windowsforms-118656-common-features-behaviors-drag-and-drop-behavior.md
The Drag-and-Drop Behavior allows users to move/reorder data items with the mouse.
The Drag-and-Drop Behavior has the following advantages over the standard DoDragDrop method:
Note
Click and hold the left mouse button for a while to drag multiple rows in the Data Grid control.
You can try out the Drag-and-Drop Behavior in the following demo applications:
Run Demo: Data Grid Run Demo: TreeList
Note
When you enable drag-and-drop behavior in a Data Grid control that is bound to a DataTable, the behavior temporarily removes the dragged row and reinserts it at a new position. The following code snippet demonstrates how this works:
var dataRow = dataTable.Rows[rowIndex];
var newRow = dataTable.NewRow();
newRow.ItemArray = dataRow.ItemArray;
dataTable.Rows.Remove(dataRow);
dataTable.Rows.InsertAt(newRow, insertPosition);
This logic is not compatible with all use cases (for example, when your table is connected to a database through a table adapter). In this case, do not enable the built-in drag-and-drop feature. Handle Drag & Drop behavior events to implement drag logic as needed.
The Behavior can be attached to the following controls:
With this Behavior, you can drag items between supported controls only. To drag items between any controls, use the standard drag-and-drop engine. See the following help topic for information: DoDragDrop.
See the help topics listed below for more information about DevExpress controls that support a built-in drag-and-drop engine.
Attach Behavior to a control to allow users to change the order of data items in that control.
Tip
The GridView supports the following drag-and-drop operations out of the box:
IList, DataTable, DataView).Use the GridView.OptionsDragDrop property to configure drag-and-drop operations that users can perform within the GridView.
Attach Behavior to each control between which users should move data items (for example, from one Data Grid to another, from a Data Grid to a Tree List). If both Data Grids/Tree Lists have the same columns and their underlying data sources expose API to add and remove items, no more actions are required. If data structure differs, you need to handle drag events to convert data items. See the following demo for an example: Drag and Drop module in the XtraTreeList MainDemo.
Attach Drag-and-Drop Behavior to main and detail views to allow users to move data items between detail views in a Data Grid with master-detail data presentation. See the following topic for an example: DragDropEvents.
Follow the steps below to associate Behavior with a control:
BehaviorManager component from Visual Studio’s Toolbox onto a form.Target property is set to a control on the form that supports Behavior. You can change the target control.Important
The attached Drag-and-Drop Behavior is disabled if the Control.AllowDrop property is set to true. It is assumed that you use the standard drag-and-drop engine in this case.
Do not confuse the Control.AllowDrop property with the Behavior’s AllowDrop property.
In the Behavior editor’s Properties section, you can specify the following options.
|
Option
|
Description
| | --- | --- | |
Target
|
Specifies the control/view to which the Behavior is attached.
| |
|
Specifies whether a preview of dragged element(s) is displayed during the operation.
| |
|
Specifies whether to show where data items will be inserted. You can customize the indicator in a DragOver event handler.
| |
|
Specifies whether users are allowed to drag data items from the control. Set this property to false if you want the control to only be a target of drag operations.
| |
|
Specifies whether users are allowed to drop data items on the control. Set this property to false if you want the control to only be a source of drag operations. If this setting is set to false, the DragOver and consequent events do not raise. You can override this setting in a DragEnter event handler.
| |
DragDropEventsName
|
Specifies the name of the DragDropEvents component that you can use to subscribe to drag events (see below).
|
Note
A drag-and-drop operation is initiated 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 property (EditorShowMode for the Data Grid, EditorShowMode for the Tree List) to a value different from Default or MouseDown. Otherwise, use the Row Indicator to drag rows (see Row Indicator Panel for the Data Grid, Node Indicator Panel for the Tree List).
Use the BehaviorManager.Attach method to associate the Behavior with a control in code. To remove the Behavior, use the BehaviorManager.Detach method.
The following code snippet associates a Behavior with two Data Grids, specifies options, and adds event handlers:
public partial class Form1 : DevExpress.XtraEditors.XtraForm {
BehaviorManager behaviorManager1;
public Form1() {
InitializeComponent();
behaviorManager1 = new BehaviorManager(components);
// Attaches the Behavior.
behaviorManager1.Attach<DragDropBehavior>(gridView1, behavior => {
behavior.Properties.AllowDrop = true;
behavior.Properties.InsertIndicatorVisible = true;
behavior.Properties.PreviewVisible = true;
// behavior.DragDrop += Behavior_DragDropToGrid1;
});
behaviorManager1.Attach<DragDropBehavior>(gridView2, behavior => {
behavior.Properties.AllowDrop = false;
behavior.Properties.InsertIndicatorVisible = false;
behavior.Properties.PreviewVisible = false;
// behavior.DragDrop += Behavior_DragDropToGrid2;
});
// Removes the Behavior.
// behaviorManager1.Detach<DragDropBehavior>(gridView1);
// behaviorManager1.Detach<DragDropBehavior>(gridView2);
}
}
Partial Public Class Form1
Inherits DevExpress.XtraEditors.XtraForm
Private behaviorManager1 As BehaviorManager
Public Sub New()
InitializeComponent()
behaviorManager1 = New BehaviorManager(components)
' Attaches the Behavior.
behaviorManager1.Attach(Of DragDropBehavior)(gridView1, Sub(behavior)
behavior.Properties.AllowDrop = True
behavior.Properties.InsertIndicatorVisible = True
behavior.Properties.PreviewVisible = True
' behavior.DragDrop += Behavior_DragDropToGrid1
End Sub)
behaviorManager1.Attach(Of DragDropBehavior)(gridView2, Sub(behavior)
behavior.Properties.AllowDrop = False
behavior.Properties.InsertIndicatorVisible = False
behavior.Properties.PreviewVisible = False
' behavior.DragDrop += Behavior_DragDropToGrid2
End Sub)
' Removes the Behavior.
' behaviorManager1.Detach(Of DragDropBehavior)(gridView1)
' behaviorManager1.Detach(Of DragDropBehavior)(gridView2)
End Sub
End Class
The BehaviorManager.Attach method returns an IDisposable object. You can also call its Dispose() method to remove Behavior.
using DevExpress.Utils.Behaviors;
using DevExpress.Utils.DragDrop;
BehaviorManager behaviorManager1 = new BehaviorManager(this.components);
//Use the Attach method to assign Behavior to a control in code.
var dragDropBehavior1 = behaviorManager1.Attach<DragDropBehavior>(gridView1, behavior => {
behavior.Properties.AllowDrop = true;
behavior.Properties.InsertIndicatorVisible = true;
behavior.Properties.PreviewVisible = true;
// behavior.DragDrop += Behavior_DragDropToGrid1;
});
//You can also use the Dispose method to remove Behavior.
dragDropBehavior1.Dispose();
Imports DevExpress.Utils.Behaviors
Imports DevExpress.Utils.DragDrop
Dim behaviorManager1 As New BehaviorManager(Me.components)
'Use the Attach method to assign Behavior to a control in code.
Dim dragDropBehavior1 = behaviorManager1.Attach(Of DragDropBehavior)(gridView1, Sub(behavior)
behavior.Properties.AllowDrop = True
behavior.Properties.InsertIndicatorVisible = True
behavior.Properties.PreviewVisible = True
' AddHandler behavior.DragDrop, AddressOf Behavior_DragDropToGrid1
End Sub)
'You can also use the Dispose method to remove Behavior.
dragDropBehavior1.Dispose()
If the BehaviorManager is no longer needed, you can call its Dispose() method to remove all Behaviors and dispose of the Manager.
This example creates and initializes the Drag and Drop Behavior to allow users to move tiles between Tile Views. In this example, Tile Views are customized at design time.
using System.ComponentModel;
using DevExpress.XtraEditors;
using DevExpress.Utils.Behaviors;
using DevExpress.XtraGrid.Views.Tile;
using DevExpress.Utils.DragDrop;
namespace DXApplication40 {
public partial class Form1 : XtraForm {
BehaviorManager behaviorManager1;
public Form1() {
InitializeComponent();
InitDragAndDropBehavior(tileView1, tileView2);
BindGrids();
}
void InitDragAndDropBehavior(TileView sourceView, TileView targetView) {
behaviorManager1 = new BehaviorManager(components);
behaviorManager1.Attach<DragDropBehavior>(sourceView, behavior => {
behavior.Properties.AllowDrop = true;
behavior.Properties.InsertIndicatorVisible = true;
behavior.Properties.PreviewVisible = true;
});
behaviorManager1.Attach<DragDropBehavior>(targetView, behavior => {
behavior.Properties.AllowDrop = true;
behavior.Properties.InsertIndicatorVisible = true;
behavior.Properties.PreviewVisible = true;
});
}
void BindGrids(){
gridControl1.DataSource = new BindingList<DataObject>() {
new DataObject() { Tile = "Tile 1" },
new DataObject() { Tile = "Tile 2" },
new DataObject() { Tile = "Tile 3" }
};
gridControl2.DataSource = new BindingList<DataObject>() {
new DataObject() { Tile = "Tile 4" },
new DataObject() { Tile = "Tile 5" }
};
}
}
public class DataObject {
public string Tile { get; set; }
}
}
Imports System.ComponentModel
Imports DevExpress.XtraEditors
Imports DevExpress.Utils.Behaviors
Imports DevExpress.XtraGrid.Views.Tile
Imports DevExpress.Utils.DragDrop
Namespace DXApplication40
Partial Public Class Form1
Inherits XtraForm
Private behaviorManager1 As BehaviorManager
Public Sub New()
InitializeComponent()
InitDragAndDropBehavior(tileView1, tileView2)
BindGrids()
End Sub
Private Sub InitDragAndDropBehavior(ByVal sourceView As TileView, ByVal targetView As TileView)
behaviorManager1 = New BehaviorManager(components)
behaviorManager1.Attach(Of DragDropBehavior)(sourceView, Sub(behavior)
behavior.Properties.AllowDrop = True
behavior.Properties.InsertIndicatorVisible = True
behavior.Properties.PreviewVisible = True
End Sub)
behaviorManager1.Attach(Of DragDropBehavior)(targetView, Sub(behavior)
behavior.Properties.AllowDrop = True
behavior.Properties.InsertIndicatorVisible = True
behavior.Properties.PreviewVisible = True
End Sub)
End Sub
Private Sub BindGrids()
gridControl1.DataSource = New BindingList(Of DataObject)() From {
New DataObject() With {.Tile = "Tile 1"},
New DataObject() With {.Tile = "Tile 2"},
New DataObject() With {.Tile = "Tile 3"}
}
gridControl2.DataSource = New BindingList(Of DataObject)() From {
New DataObject() With {.Tile = "Tile 4"},
New DataObject() With {.Tile = "Tile 5"}
}
End Sub
End Class
Public Class DataObject
Public Property Tile() As String
End Class
End Namespace
The DragDropEvents component is added to your form when you attach the Behavior to a control in the designer. You can find its name in the Behavior editor’s Properties section. Use this component to handle the following events:
|
Event
|
Description
| | --- | --- | |
|
Occurs when a drag-and-drop operation is initiated.
| |
|
Occurs when a data item is dragged into the control’s bounds.
| |
|
Occurs when a data item is dragged over the control’s bounds.
| |
|
Occurs when a data item is dragged out of the control’s bounds.
| |
|
Occurs when a data item is dropped on the control.
| |
|
Occurs when a drag-and-drop operation is completed.
|
You can add event handlers in the designer or in code.
dragDropEvents1.DragDrop += dragDropEvents1_DragDrop;
dragDropEvents1.DragOver += dragDropEvents1_DragOver;
AddHandler dragDropEvents1.DragDrop, AddressOf dragDropEvents1_DragDrop
AddHandler dragDropEvents1.DragOver, AddressOf dragDropEvents1_DragOver
Note
When you handle the DragOver event and set e.Handled to true, event arguments are not automatically calculated on subsequent DragOver events. To preserve automatic calculations, call e.Default() before modifying event arguments.
If you attach the Behavior in code, the DragDropEvents component is not added to the form. Use the Behavior’s events in this case.
behaviorManager1.Attach<DragDropBehavior>(gridView1, behavior => {
behavior.DragDrop += Behavior_DragDropToGrid2;
});
behaviorManager1.Attach(Of DragDropBehavior)(gridView1, Sub(behavior)
AddHandler behavior.DragDrop, AddressOf Behavior_DragDropToGrid1
End Sub)
The static (Shared in VB) DragDropManager.Default property specifies the default Drag-and-Drop Behavior Manager. You can use this Manager handle drag-and-drop events in a centralized way or specify settings. See the following demo for an example: Drag and Drop module in the XtraTreeList MainDemo.
Business objects must have a default constructor with no parameters if Behavior is attached to data-aware controls that store these objects defined in code. Otherwise, rows that display these objects cannot be moved between controls.
If a business object does not have a default constructor, you must handle the target control’s DragOver and DragDrop events to move/copy the dragged item. See DragDrop for an example.
Note
The Behavior copies/moves data displayed in a control, not the data source’s records. For example, if a data object exposes fields that are not associated with the control’s columns, the values of these fields will be lost.