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.
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);
}
Private mouseDownPosition As Point
Private Sub radListControl1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
Me.mouseDownPosition = e.Location
End Sub
Private Sub radListControl1_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
If e.Button <> MouseButtons.Left Then
Return
End If
Dim listControl As RadListControl = TryCast(sender, RadListControl)
Dim draggedItem As RadListVisualItem = TryCast(listControl.ElementTree.GetElementAtPoint(Me.mouseDownPosition), RadListVisualItem)
If draggedItem IsNot Nothing AndAlso IsRealDrag(mouseDownPosition, e.Location) Then
TryCast(sender, RadListControl).DoDragDrop(draggedItem.Data, DragDropEffects.Move)
End If
End Sub
Private Shared Function IsRealDrag(ByVal mousePosition As Point, ByVal initialMousePosition As Point) As Boolean
Return (Math.Abs(mousePosition.X - initialMousePosition.X) >= SystemInformation.DragSize.Width) OrElse (Math.Abs(mousePosition.Y - initialMousePosition.Y) >= SystemInformation.DragSize.Height)
End Function
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;
}
}
Private Sub radListControl1_DragEnter(ByVal sender As Object, ByVal e As DragEventArgs)
Dim listControl As RadListControl = TryCast(sender, RadListControl)
Dim draggedItem As RadListDataItem = TryCast(e.Data.GetData(GetType(RadListDataItem)), RadListDataItem)
If draggedItem.OwnerControl Is listControl Then
e.Effect = DragDropEffects.None
Else
e.Effect = DragDropEffects.Move
End If
End Sub
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);
}
}
Private Sub radListControl2_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs)
Dim listControl As RadListControl = TryCast(sender, RadListControl)
Dim draggedItem As RadListDataItem = TryCast(e.Data.GetData(GetType(RadListDataItem)), RadListDataItem)
Dim dragedData As CustomObject = TryCast(draggedItem.DataBoundItem, CustomObject)
If myList1.Contains(dragedData) Then
myList1.Remove(dragedData)
myList.Add(dragedData)
Else
myList.Remove(dragedData)
myList1.Add(dragedData)
End If
End Sub
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;
}
Private myList As BindingList(Of CustomObject)
Private myList1 As BindingList(Of CustomObject)
Public Sub New()
InitializeComponent()
myList = New BindingList(Of CustomObject)()
myList1 = New BindingList(Of CustomObject)()
myList.Add(New CustomObject(1, "Outdoor"))
myList.Add(New CustomObject(8, "Hardware"))
myList.Add(New CustomObject(3, "Tools"))
myList1.Add(New CustomObject(6, "Books"))
myList1.Add(New CustomObject(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
AddHandler radListControl1.MouseDown, AddressOf radListControl1_MouseDown
AddHandler radListControl1.MouseMove, AddressOf radListControl1_MouseMove
AddHandler radListControl1.DragEnter, AddressOf radListControl1_DragEnter
AddHandler radListControl1.DragDrop, AddressOf radListControl2_DragDrop
AddHandler radListControl2.MouseDown, AddressOf radListControl1_MouseDown
AddHandler radListControl2.MouseMove, AddressOf radListControl1_MouseMove
AddHandler radListControl2.DragEnter, AddressOf radListControl1_DragEnter
AddHandler radListControl2.DragDrop, AddressOf radListControl2_DragDrop
End Sub
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;
}
}
Public Class CustomObject
Public Property ID() As Integer
Public Property Category() As String
Public Sub New(ByVal iD As Integer, ByVal category As String)
Me.ID = iD
Me.Category = category
End Sub
End Class