While surfing thru different forum I noticed that, lots of people are actually facing issues while trying to implement the drag and drop feature. The main problem arises while trying to drag from a ListBox to a panel like canvas. In this post, I will go thru the steps to demonstrate such feature.
Here I will use Telerik control to give out the demonstration. You can download the trial version of the dlls from Telerik Silverlight Control Page. I have implemented the demo using Silverlight 4 Beta 1. The same thing is also possible in earlier version of Silverlight. You can download Silverlight SDK from Silverlight Site. To develop apps in Silverlight 4 you must need Visual Studio 2010 Beta 2 which you can download from Microsoft site.
So, lets go for implementing the same. Create a Silverlight project. Lets create a ListBox and a Canvas inside the LayoutRoot:
<Grid x:Name="LayoutRoot" Background="White"> <Grid.ColumnDefinitions> <ColumnDefinition Width="150"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <ListBox x:Name="lstBox" Margin="10" Grid.Column="0"/> <Canvas x:Name="cnvDropBox" Background="Yellow" Margin="10" Grid.Column="1"/> </Grid>Now in the code behind, we have to register the Drag and Drop events for the ListBox & Canvas. Use RadDragAndDropManager class to register the same.
RadDragAndDropManager.AddDragInfoHandler(lstBox, OnDragInfo); RadDragAndDropManager.AddDragQueryHandler(lstBox, OnDragQuery); RadDragAndDropManager.AddDropInfoHandler(cnvDropBox, OnDropInfo); RadDragAndDropManager.AddDropQueryHandler(cnvDropBox, OnDropQuery); RadDragAndDropManager.SetAllowDrop(cnvDropBox, true);The implementation of the events will be as below:
private void OnDragQuery(object sender, DragDropQueryEventArgs e) { if (e.Options.Status == DragStatus.DragQuery) { var draggedListBoxItem = e.Options.Source as Image; e.Options.DragCue = draggedListBoxItem.Source; e.Options.Payload = draggedListBoxItem.Source; } e.QueryResult = true; e.Handled = true; }
private void OnDragInfo(object sender, DragDropEventArgs e) { if (e.Options.Status == DragStatus.DragComplete) { // comment this block if you are going to clone lstBox.Items.Remove(e.Options.Source); } }
private void OnDropInfo(object sender, DragDropEventArgs e) { var droppablePanel = e.Options.Destination; if (e.Options.Status == DragStatus.DropComplete && droppablePanel is Canvas) { FrameworkElement dragableControl = null; Point desiredPosition = new Point(); Point currentDragPoint = e.Options.CurrentDragPoint; Point canvasPosition = cnvDropBox.TransformToVisual(null).Transform(new Point()); if (e.Options.Source is Image) { // create the new instance & update the necessary properties // this step is require if you are going to make a clone Image tempDragableControl = e.Options.Source as Image; dragableControl = new Image() { Source = tempDragableControl.Source }; cnvDropBox.Children.Add(dragableControl); } desiredPosition.X = currentDragPoint.X - canvasPosition.X; desiredPosition.Y = currentDragPoint.Y - canvasPosition.Y; dragableControl.SetValue(Canvas.LeftProperty, desiredPosition.X); dragableControl.SetValue(Canvas.TopProperty, desiredPosition.Y); } }
private void OnDropQuery(object sender, DragDropQueryEventArgs e) { var droppablePanel = e.Options.Destination; if (e.Options.Status == DragStatus.DropDestinationQuery && droppablePanel is Canvas) { e.QueryResult = true; e.Handled = true; } }
As I am using Image inside the ListBoxItem, hence OnDragQuery I am setting the Source as an Image to the DragCue & PayLoad properties. OnDragInfo I am removing item from the ListBox. If you don’t want to remove the dragged image from the ListBox then just remove that line. OnDropInfo I am just placing the Image to the appropriate position which we will get as CurrentDragPoint in the DragDropEventArgs.
This is a sample demonstration. So, you have to explore it more to fulfil your requirement.
Download Sample Application: Drag And Drop ListBoxItem to Canvas Demo