New to Telerik UI for WinForms? Download free 30-day trial

Drag and Drop in Bound Mode

This article demonstrates how you can implement drag and drop operation between two bound RadListControl controls. This example is using the ole drag and drop

Figure 1: The final result.

WinForms RadListControl Drag Drop Bound Mode

The drag and drop functionality is achieved with the help of four events: MouseDown, MouseMove, DragEnter, DragDrop:

1. Handling the MouseDown and MouseMove events: The MouseDown event is used for saving the position of the clicked element. It will be used later for getting the element under the mouse. The MouseMove event can be used to start the drag and drop operation. It is started with the DoDragDrop method only if the left mouse button is used and a valid item is clicked.

The IsRealDrag method returns true only if the mouse have moved certain amount of pixels (determined by the operating system).

MouseDown and MouseMove


private Point mouseDownPosition;

void radListControl1_MouseDown(object sender, MouseEventArgs e)
{
    this.mouseDownPosition = e.Location;
}

void radListControl1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button != MouseButtons.Left)
    {
        return;
    }

    RadListControl listControl = sender as RadListControl;
    RadListVisualItem draggedItem = listControl.ElementTree.GetElementAtPoint(this.mouseDownPosition) as RadListVisualItem;
    if (draggedItem != null&& IsRealDrag(mouseDownPosition, e.Location))
    {
        (sender as RadListControl).DoDragDrop(draggedItem.Data, DragDropEffects.Move);
    }
}
private static bool IsRealDrag(Point mousePosition, Point initialMousePosition)
{
    return (Math.Abs(mousePosition.X - initialMousePosition.X) >= SystemInformation.DragSize.Width) ||
        (Math.Abs(mousePosition.Y - initialMousePosition.Y) >= SystemInformation.DragSize.Height);
}

2. Handling the DragEnter event: This event will fire when the mouse is hovering over a control that allows dropping. Here you can use it to disable the drop operation within the same control.

The DragEnter event handler

void radListControl1_DragEnter(object sender, DragEventArgs e)
{
    RadListControl listControl = sender as RadListControl;
    RadListDataItem draggedItem = e.Data.GetData(typeof(RadListDataItem)) as RadListDataItem;

    if (draggedItem.OwnerControl == listControl)
    {
        e.Effect = DragDropEffects.None;
    }
    else
    {
        e.Effect = DragDropEffects.Move;
    }
}

3. Handling the DragDrop event: This is the most important event. In it you have access to both, the dragged element and the control where the item is dropped. This allows you to handle the drop operation appropriately according to your specific requirements. In this case, both controls are bound, and this allows you to just add/remove items from/to their data source (the changes will be immediately reflected by the controls).

The DragDrop event handler

void radListControl2_DragDrop(object sender, DragEventArgs e)
{
    RadListControl listControl = sender as RadListControl;
    RadListDataItem draggedItem = e.Data.GetData(typeof(RadListDataItem)) as RadListDataItem;

    MyCustomObject dragedData = draggedItem.DataBoundItem as MyCustomObject;

    if (myList1.Contains(dragedData))
    {
        myList1.Remove(dragedData);
        myList.Add(dragedData);
    }
    else
    {
        myList.Remove(dragedData);
        myList1.Add(dragedData);
    }
}

Additionally, you should enable the AllowDrop property for both controls. With this example you can move from the first RadListControl to the second and vice versa. Along with this, the following snippet shows how you can bind the controls and subscribe to the events. The same events are used for both controls.

Controls initialization


BindingList<MyCustomObject> myList;
BindingList<MyCustomObject> myList1;

public DragAndDrop()
{
    InitializeComponent();

    myList = new BindingList<MyCustomObject>();
    myList1 = new BindingList<MyCustomObject>();

    myList.Add(new MyCustomObject(1, "Outdoor"));
    myList.Add(new MyCustomObject(8, "Hardware"));
    myList.Add(new MyCustomObject(3, "Tools"));
    myList1.Add(new MyCustomObject(6, "Books"));
    myList1.Add(new MyCustomObject(2, "Appliances"));

    radListControl1.DataSource = myList;
    radListControl1.DisplayMember = "Category";
    radListControl1.ValueMember = "ID";
    radListControl1.AllowDrop = true;

    radListControl2.DataSource = myList1;
    radListControl2.DisplayMember = "Category";
    radListControl2.ValueMember = "ID";
    radListControl2.AllowDrop = true;

    radListControl1.MouseDown += radListControl1_MouseDown;
    radListControl1.MouseMove += radListControl1_MouseMove;
    radListControl1.DragEnter += radListControl1_DragEnter;
    radListControl1.DragDrop += radListControl2_DragDrop;

    radListControl2.MouseDown += radListControl1_MouseDown;
    radListControl2.MouseMove += radListControl1_MouseMove;
    radListControl2.DragEnter += radListControl1_DragEnter;
    radListControl2.DragDrop += radListControl2_DragDrop;
}

To complete the example you can use the following sample class.

Sample business object for the example


public class MyCustomObject
{
    public int ID { get; set; }

    public string Category { get; set; }
    public MyCustomObject(int iD, string category)
    {
        this.ID = iD;
        this.Category = category;
    }
}
In this article