How to: Drag XtraGrid rows to the XtraTreeList
- 9 minutes to read
Tip
Starting with version 17.2, you can attach the Drag-and-Drop Behavior to controls (for example, XtraGrid, XtraTreeList) to enable drag-drop operations. An example that uses the Drag-and-Drop Behavior is available at GitHub: Drag-and-Drop Grid Rows to the TreeList.
The following example demonstrates even-based implementation of drag-drop operations:
- Handle the grid’s MouseDown event to obtain the clicked data row.
- Set the GridView’s OptionsBehavior.EditorShowMode option to
EditorShowMode.MouseUp
orEditorShowMode.Click
to prevent a cell editor from being opened on theMouseDown
event. - Handle the grid’s MouseMove event to initialize a drag operation.
- Set the TreeList’s AllowDrop property to true to allow the TreeList to accept data that a user drags onto it.
Handle the TreeList’s DragDrop event to append a new node. Use the TreeList.AppendNode. The event handler uses the
TreeList.GetDXDragEventArgs
extension method to obtain the following event arguments:TargetNode
— specifies the node onto which the grid row is dropped.DragInsertPosition
— specifies how to insert the node (as a child node, before the target node, or after the target node).
In this example, the TreeList is bound to a BindingList<T>.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.XtraTreeList;
using DevExpress.XtraGrid;
using DevExpress.XtraTreeList.Nodes;
using DevExpress.XtraTreeList.Columns;
using DevExpress.XtraEditors;
namespace DragAndDropRows {
public partial class Form1 : XtraForm {
GridHitInfo hitInfo = null;
BindingList<Person> gridDataSource = new BindingList<Person>();
public Form1() {
InitializeComponent();
InitGrid();
InitTreeList();
}
void InitGrid() {
gridDataSource.Add(new Person("John", "Smith", "USA"));
gridDataSource.Add(new Person("Michael", "Suyama", "UK"));
gridDataSource.Add(new Person("Laura", "Callahan", "UK"));
gridDataSource.Add(new Person("Gerard", "Blain", "France"));
gridDataSource.Add(new Person("Sergio", "Rubini", "Italy"));
gridDataSource.Add(new Person("Andrew", "Fuller", "USA"));
gridControl.DataSource = gridDataSource;
// Enable drag-and-drop operations within the GridView.
gridView.OptionsBehavior.EditorShowMode = DevExpress.Utils.EditorShowMode.Click;
}
void InitTreeList() {
treeList.DataSource = new BindingList<PersonEx>() ;
// Specify the data source field that contains node identifiers.
treeList.KeyFieldName = "ID";
// Specify the data source field that contains parent node identifiers.
treeList.ParentFieldName = "ParentID";
// Allow the control to accept data that a user drags onto it.
treeList.AllowDrop = true;
}
private void gridControl_MouseDown(object sender, MouseEventArgs e) {
hitInfo = gridView.CalcHitInfo(new Point(e.X, e.Y));
}
// Initialize a drag-and-drop operation.
private void gridControl_MouseMove(object sender, MouseEventArgs e) {
if (hitInfo == null) return;
if (e.Button != MouseButtons.Left) return;
Rectangle dragRect = new Rectangle(new Point(
hitInfo.HitPoint.X - SystemInformation.DragSize.Width / 2,
hitInfo.HitPoint.Y - SystemInformation.DragSize.Height / 2), SystemInformation.DragSize);
if (!(hitInfo.RowHandle == GridControl.InvalidRowHandle) && !dragRect.Contains(new Point(e.X, e.Y))) {
Object data = gridView.GetRow(hitInfo.RowHandle);
gridControl.DoDragDrop(data, DragDropEffects.Copy);
}
}
private void treeList_DragEnter(object sender, DragEventArgs e) {
e.Effect = DragDropEffects.Copy;
}
// Add a node to the TreeList when a grid row is dropped.
private void treeList_DragDrop(object sender, DragEventArgs e) {
// Get extended arguments of the drag event.
DXDragEventArgs args = treeList.GetDXDragEventArgs(e);
// Get how a node is inserted (as a child, before or after a node, or at the end of the node collection).
DragInsertPosition position = args.DragInsertPosition;
Person dataRow = e.Data.GetData(typeof(DragAndDropRows.Person)) as Person;
if (dataRow == null) return;
int parentID = (int)treeList.RootValue;
// Get the node over which the row is dropped.
TreeListNode node = args.TargetNode;
// Add a node at the root level.
if (node == null) {
treeList.AppendNode((new PersonEx(dataRow, parentID)).ToArray(), null);
}
else {
// Add a child node to the target node.
if (position == DragInsertPosition.AsChild) {
parentID = Convert.ToInt32(node.GetValue("ID"));
Object[] targetObject = (new PersonEx(dataRow, parentID)).ToArray();
treeList.AppendNode(targetObject, node);
}
// Insert a node before the target node.
if (position == DragInsertPosition.Before) {
parentID = Convert.ToInt32(node.GetValue("ParentID"));
Object[] targetObject = (new PersonEx(dataRow, parentID)).ToArray();
TreeListNode newNode = treeList.AppendNode(targetObject, node.ParentNode);
int targetPosition;
if (node.ParentNode == null)
targetPosition = treeList.Nodes.IndexOf(node);
else targetPosition = node.ParentNode.Nodes.IndexOf(node);
treeList.SetNodeIndex(newNode, targetPosition);
}
node.Expanded = true;
}
}
private void treeList_DragOver(object sender, DragEventArgs e) {
e.Effect = DragDropEffects.Copy;
}
}
}
See Also