DragDropEvents.DragDrop Event

Occurs when a data element is dropped on the control.

Namespace: DevExpress.Utils.DragDrop

Assembly: DevExpress.Utils.v20.1.dll

Declaration

[DXCategory("DragDrop")]
public event DragDropEventHandler DragDrop
<DXCategory("DragDrop")>
Public Event DragDrop As DragDropEventHandler

Event Data

The DragDrop event's data class is DragDropEventArgs. The following properties provide information specific to this event:

Property Description
Action Gets or sets the drag-and-drop action (Copy, Move, etc.) to perform. Inherited from DXDragEventArgs.
Cursor Gets or sets the mouse pointer. Inherited from DXDragEventArgs.
CustomData Gets or sets custom data associated with the operation.
Data Gets or sets the data elements being dragged. Inherited from DXDragEventArgs.
Handled Gets or sets whether the event was handled and allows you to suppress the default action. Inherited from DXDefaultEventArgs.
InsertType Gets or sets whether dragged data elements are inserted before or after a data element under the mouse pointer, or as a child (for tree list only). Inherited from DragOverEventArgsBase.
KeyState Gets the pressed mouse buttons (left, middle, right) and modifier keys (Shift, Ctrl, Alt). Inherited from DXDragEventArgs.
Location Gets the mouse cursor's position. Inherited from DXDragEventArgs.
Source Gets the source control. Inherited from DXDragEventArgs.
Tag Gets or sets custom data associated with the drag-and-drop operation. Inherited from DragOverEventArgsBase.
Target Gets the target control. Inherited from DXDragEventArgs.

Examples

The example below shows how to copy data from a tree list to a grid.

using DevExpress.Utils.DragDrop;

//The code below assumes that you are moving data from a tree list to a grid.
//Create new grid rows, and populate them with data from tree list nodes.
private void dragDropEvents1_DragDrop(object sender, DragDropEventArgs e) {
    List<TreeListNode> list = e.Data as List<TreeListNode>;
    foreach (TreeListNode node in list) {
        gridView1.AddNewRow();
        gridView1.SetRowCellValue(GridControl.NewItemRowHandle, gridView1.Columns["DEPARTMENT"], node.GetValue(colDEPARTMENT1));
    }
    e.Handled = true;
}
NOTE

When you handle the DragDrop event for a grid view, use the static (Shared in VB) DragDropGridEventArgs.GetDragDropGridEventArgs method to calculate arguments specific to the grid view.

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

dragDropEvents1.DragDrop += Behavior_DragDrop;

private void Behavior_DragDrop(object sender, DragDropEventArgs e) {
   DragDropGridEventArgs args = DragDropGridEventArgs.GetDragDropGridEventArgs(e);
   //You can also cast DragDropEventArgs to DragDropGridEventArgs.
   //DragDropGridEventArgs args = (DragDropGridEventArgs)e;
}
NOTE

Run the XtraTreeList or XtraGrid demo and click Open Solution for more examples.

The Drag-and-Drop Behavior allows you to support drag-and-drop operations between detail views in a grid control.

To allow users to move child rows between detail views, 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.

The code below shows how to implement this approach. It is assumed the behavior Manager is placed to the component tray and the Behavior Manager is attached to the main view in the Visual Studio Designer.

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;
}

If the application uses business objects (for example, Persistent Objects), these objects must have a default constructor to allow the Drag-and-Drop Behavior to move/copy data items between controls.

In the example below, business objects are stored in an XPCollection. To load and save the business objects, the collection uses a Session that is also passed to every business object in its constructor. If a business object does not have a default constructor, you must handle the target control's DragOver and DragDrop events to manually move/copy the dragged item.

The DragOver event handler sets the Action event argument to Move to allow users to drop data items to the target control. The DragDrop event handler manually moves the dragged item from the source to the target control.

using DevExpress.Data.Filtering;
using DevExpress.Utils.DragDrop;
using DevExpress.Xpo;
using DevExpress.Xpo.DB;
using DevExpress.Xpo.Metadata;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraTreeList;
using DevExpress.XtraTreeList.Nodes;

private UnitOfWork treeListSession = new UnitOfWork();
private UnitOfWork gridSession = new UnitOfWork();

XpoDefault.DataLayer = new SimpleDataLayer(new InMemoryDataStore());
XpoDefault.Session = null;
if (Convert.ToInt32(treeListSession.Evaluate<Customer>(new AggregateOperand(null, null, Aggregate.Count, null), null)) == 0) {
    for (int i = 0; i <= 9; i++)
        new Customer(treeListSession) { Name = string.Format("Name {0}", i) };
    treeListSession.CommitChanges();
}
if (Convert.ToInt32(gridSession.Evaluate<Customer>(new AggregateOperand(null, null, Aggregate.Count, null), null)) == 0) {
    for (int i = 0; i <= 9; i++)
        new Customer(treeListSession) { Name = string.Format("Name {0}", i) };
    gridSession.CommitChanges();
}

XPClassInfo treeClassInfo = treeListSession.Dictionary.GetClassInfo(typeof(Customer));
treeList1.DataSource = new XPCollection(treeListSession, treeClassInfo);            
XPClassInfo gridClassInfo = gridSession.Dictionary.GetClassInfo(typeof(Customer));
gridControl1.DataSource = new XPCollection(gridSession, gridClassInfo);


private void dragDropEvents1_DragOver(object sender, DragOverEventArgs e)  {
    if (object.ReferenceEquals(e.Source, e.Target))
        return;
    e.Default();
    e.Action = DragDropActions.Move;
    e.Cursor = Cursors.Arrow;
}


private void dragDropEvents1_DragDrop(object sender, DragDropEventArgs e) {
    GridView view = e.Source as GridView;
    TreeList treeList = e.Target as TreeList;
    if (view != null && treeList != null) {
        int[] rowHandles = e.Data as int[];
        Customer customer = view.GetRow(rowHandles[0]) as Customer;

        XPCollection xpCollection = treeList.DataSource as XPCollection;

        Customer cloneCustomer = new Customer(treeListSession);
        cloneCustomer.Name = customer.Name;
        customer.Delete();
        treeListSession.CommitChanges();
        gridSession.CommitChanges();
        xpCollection.Add(cloneCustomer);


        TreeListHitInfo hitInfo = treeList.CalcHitInfo(treeList.PointToClient(e.Location));
        TreeListNode targetNode = hitInfo.Node;
        TreeListNode newNode = treeList.FindNodeByFieldValue("Oid", cloneCustomer.Oid);

        switch (e.InsertType) {
            case InsertType.None:
            case InsertType.AsChild:
            case InsertType.After:
            case InsertType.Before:
                treeList.MoveNode(newNode, newNode.ParentNode, false, treeList.Nodes.IndexOf(targetNode));
                break;
        }
    }
}

class Customer : XPObject {
    [Size(SizeAttribute.DefaultStringMappingFieldSize)]
    public string Name {
        get {
            return name;
        }
        set {
            SetPropertyValue("Name", ref name, value);
        }
    }

    private string name;

    public Customer(Session session) : base(session) {
    }
}
See Also