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

ListControlDragDropService

Since R1 2017 SP RadListControl supports ListControlDragDropService. It is necessary to set the AllowDragDrop property to true in order to enable its functionality. The benefits that come with this service are:

  • Items drag and drop behavior in unbound mode comes out of the box within the same RadListControl or between two RadListControls.

  • ListControlDragDropService allows you to achieve drag and drop behavior in bound mode through its public API.

Drag and drop in unbound mode out of the box

The following steps demonstrates how to populate two RadListControls with items in unbound mode and enable the drag and drop functionality between them.

1. Add two RadListControls on your form and add some items via the RadListDataItem Collection Editor. 2. Set the AllowDragDrop property to true for both of the RadListControls either at design time in the Properties section of Visual Studio or via code at run time. 3. Run the application and try to reorder the items.

Figure 1: Drag and drop in unbound mode

WinForms RadListControl Drag and Drop in Unbound mode

Drag and drop in bound mode by using ListControlDragDropService

1. Consider that you have two RadListControls which are bound to a BindingList of custom Item objects.


public ListControlBoundDragDrop()
{
    InitializeComponent();
    BindingList<Item> items = new BindingList<Item>();
    BindingList<Item> items2 = new BindingList<Item>();
    for (int i = 0; i < 20; i++)
    {
        items.Add(new Item(i, "Item.1." + i));
        items2.Add(new Item(i, "Item.2." + i));
    }

    this.radListControl1.DataSource = items;
    this.radListControl1.DisplayMember = "Name";
    this.radListControl1.ValueMember = "Id";

    this.radListControl2.DataSource = items2;
    this.radListControl2.DisplayMember = "Name";
    this.radListControl2.ValueMember = "Id";
}

public class Item
{
    public int Id { get; set; }

    public string Name { get; set; }

    public Item(int id, string name)
    {
        this.Id = id;
        this.Name = name;
    }
}

2. Set the AllowDragDrop property for both of the RadListControls to true.


this.radListControl1.AllowDragDrop = true;
this.radListControl2.AllowDragDrop = true;

3. Handle the service's events in order to achieve the desired drag and drop behavior. In the PreviewDragStart event of ListControlDragDropService you can store the dragged data item. Set the PreviewDragStartEventArgs.CanStart property to true in order to indicate the drag operation is allowed. The PreviewDragOver event allows you to control on what targets the item being dragged can be dropped on. The PreviewDragDrop event allows you to get a handle on all the aspects of the drag and drop operation, the source (drag) RadListControl, the destination (target) control, as well as the item being dragged. This is where we will initiate the actual physical move of the item(s) from RadListControl to the target control.


private void ListControlBoundDragDrop_Shown(object sender, EventArgs e)
{
    this.radListControl1.ListElement.DragDropService.PreviewDragStart += DragDropService_PreviewDragStart;
    this.radListControl1.ListElement.DragDropService.PreviewDragOver += DragDropService_PreviewDragOver;
    this.radListControl1.ListElement.DragDropService.PreviewDragDrop += DragDropService_PreviewDragDrop;
}

RadListDataItem draggedItem = null;

private void DragDropService_PreviewDragStart(object sender, Telerik.WinControls.PreviewDragStartEventArgs e)
{
    RadListVisualItem draggedVisualitem = e.DragInstance as RadListVisualItem;
    if (draggedVisualitem != null)
    {
        draggedItem = draggedVisualitem.Data;
        e.CanStart = true;
    }
    else
    {
        e.CanStart = false;
    }
}

private void DragDropService_PreviewDragOver(object sender, Telerik.WinControls.RadDragOverEventArgs e)
{
    RadListVisualItem targetVisualItem = e.HitTarget as RadListVisualItem;
    RadListElement targetListElement = e.HitTarget as RadListElement;
    if (targetVisualItem != null || targetListElement != null)
    {
        e.CanDrop = true;
    }
    else
    {
        e.CanDrop = false;
    }
}

private void DragDropService_PreviewDragDrop(object sender, Telerik.WinControls.RadDropEventArgs e)
{ 
    RadListVisualItem targetVisualItem = e.HitTarget as RadListVisualItem;
    RadListElement targetListElement = e.HitTarget as RadListElement;
    if (targetVisualItem != null)
    {
        targetListElement = targetVisualItem.Data.Owner as RadListElement;
    }
    if (targetListElement == null)
    {
        return;
    }
    e.Handled = true;
    BindingList<Item> targetSourceItems = targetListElement.DataSource as BindingList<Item>;
    BindingList<Item> draggtedSourceItems = this.draggedItem.Owner.DataSource as BindingList<Item>;
    int draggedItemIndex = draggtedSourceItems.IndexOf(this.draggedItem.DataBoundItem as Item);
    int targetItemIndex = targetVisualItem == null ? targetSourceItems.Count-1 : targetSourceItems.IndexOf(targetVisualItem.Data.DataBoundItem as Item);

    Item item = this.draggedItem.DataBoundItem as Item;
    targetSourceItems.RemoveAt(draggedItemIndex);
    targetSourceItems.Insert(targetItemIndex, new Item(item.Id, item.Name));
}

Figure 2: Drag and Drop in Bound Mode

WinForms RadListControl Drag and Drop in Bound Mode