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

Combining RadDragDropService and OLE drag-and-drop

This article demonstrates a sample approach how to achieve drag and drop functionality between RadListView and RadListControl. For this purpose, we will use a combination between the RadDragDropService, supported by the RadListView control, and the OLE drag-and-drop, which is supported by all controls from the Telerik UI for WinForms suite.

Let’s assume that our RadListView is in bound mode and its ViewType property is set to IconsView. The RadListControl is populated manually with items. Set the AllowDrop property to true for both of the controls. Additionally, you need to set the RadListView.AllowDragDrop property to true as well.

Populating with data


BindingList<string> items = new BindingList<string>();
for (int i = 0; i < 10; i++)
{
    items.Add("Item" + i);                
    this.radListControl1.Items.Add("ListControlItem" + i);
}

this.radListView1.DataSource = items;
this.radListView1.AllowDragDrop = true;
this.radListView1.AllowDrop = true;
this.radListControl1.AllowDrop = true;
this.radListView1.ViewType = Telerik.WinControls.UI.ListViewType.IconsView;

Drag and drop from RadListView to RadListControl using RadDragDropService

Figure 1: Drag and drop from RadListView to RadListControl using RadDragDropService

WinForms RadListView Drag and drop from RadListView to RadListControl using RadDragDropService

To implement drag and drop functionality for this scenario, we will use the ListViewElement.DragDropService, which is a derivative of the In the PreviewDragOver event allow dropping over a RadListElement. The PreviewDragDrop event performs the actual inserting of the dragged item into the RadListControl.Items collection:

Handling the RadDragDropService's events


private void DragDropService_PreviewDragOver(object sender, Telerik.WinControls.RadDragOverEventArgs e)
{
    e.CanDrop = e.HitTarget is RadListElement;
}

private void DragDropService_PreviewDragDrop(object sender, Telerik.WinControls.RadDropEventArgs e)
{ 
    BaseListViewVisualItem draggedItem = e.DragInstance as BaseListViewVisualItem;
    RadListElement listElement = e.HitTarget as RadListElement;

    if (listElement == null)
    {
        return;
    }
    e.Handled = true;         
    RadListControl listControl = listElement.ElementTree.Control as RadListControl;
    RadListVisualItem targetItem = listControl.ElementTree.GetElementAtPoint(e.DropLocation) as RadListVisualItem;
    int indexToInsert;
    if (targetItem != null)
    {
        indexToInsert = targetItem.Data.RowIndex;
    }
    else
    {
        indexToInsert = listControl.Items.Count;
    }
    RadListDataItem newItem = new RadListDataItem(draggedItem.Data.Text);
    listControl.Items.Insert(indexToInsert, newItem);

    draggedItem.Data.ListView.Items.Remove(draggedItem.Data);
}

Drag and drop from RadListControl to RadListView using the OLE drag-and-drop

Figure 2: Drag and drop from RadListControl to RadListView using the OLE drag-and-drop

WinForms RadListView Drag and drop from RadListControl to RadListView using the OLE drag-and-drop

1. Firstly, we should start the drag and drop operation using the RadListControl.MouseMove event when the left mouse button is pressed. We should keep the mouse down location in the RadListControl.MouseDown event. Afterwards, allow dragging over the RadListView via the Effect argument of the DragEventArgs in the RadListView.DragEnter event handler:

Starting the drag and drop operation


private Point mouseDownPosition;
private bool isDragging;
private void radListControl1_MouseDown(object sender, MouseEventArgs e)
{
    this.mouseDownPosition = e.Location;
}
private void radListControl1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button != MouseButtons.Left)
    {
        this.isDragging = false;
        return;
    }
    if (this.isDragging)
    {
        return;
    }
    if (this.ShouldBeginDrag(this.mouseDownPosition, e.Location))
    {
        RadListVisualItem draggedItem = this.radListControl1.ElementTree.GetElementAtPoint(this.mouseDownPosition) as RadListVisualItem;
        if (draggedItem != null)
        {
            this.isDragging = true;
            //start the drag and drop operation
            (sender as RadListControl).DoDragDrop(draggedItem.Data, DragDropEffects.Copy);
        }
    }
}

private bool ShouldBeginDrag(Point current, Point capture)
{
    Size dragSize = SystemInformation.DragSize;
    Rectangle dragRect = new Rectangle(capture.X - dragSize.Width / 2,
        capture.Y - dragSize.Height / 2, dragSize.Width, dragSize.Height);
    return !dragRect.Contains(current);
}

private void radListView1_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Copy;
}

2. In the RadListView.DragDrop event you need to get the location of the mouse and convert it to a point that the RadListView can use to get the element underneath the mouse. Afterwards, insert the dragged item on the specific position. We should reset the stored mouse down location as well:

Handle the drop operation


private void radListView1_DragDrop(object sender, DragEventArgs e)
{
    RadListView listView = sender as RadListView;
    Point point = listView.PointToClient(new Point(e.X, e.Y));
    BaseListViewVisualItem targetItem = listView.ElementTree.GetElementAtPoint(point) as BaseListViewVisualItem;
    RadListDataItem draggedItem = e.Data.GetData(typeof(RadListDataItem)) as RadListDataItem;

    BindingList<string> targetDataSource = listView.DataSource as BindingList<string>; 
    if (targetDataSource != null)
    {
        //you are dropping over an item
        if (targetItem != null)
        {
            int targetIndex = listView.Items.IndexOf(targetItem.Data);

            targetDataSource.Insert(targetIndex, draggedItem.Text);
        }
        else // you are dropping over the ListViewElement
        {
            targetDataSource.Add(draggedItem.Text);
        }
    }

    int indexToRemove = this.radListControl1.Items.IndexOf(draggedItem);
    if (indexToRemove > -1)
    {
        this.radListControl1.Items.RemoveAt(indexToRemove);
    }
    this.mouseDownPosition = Point.Empty;
    this.isDragging = false;
}

private void radListControl1_MouseUp(object sender, MouseEventArgs e)
{
    this.mouseDownPosition = Point.Empty;
    this.isDragging = false;
}