In some occasions you will need to drag & drop items between different objects in your Silverlight application. Although in Windows Forms is very easy to achieve this goal (because you have the events DragEnter, DragDrop), in Silverlight you can do the same with little tricks. In this example I will show you how to do drag & drop over a canvas.
We are going to create a project, called Freedom in the Sky. We have a custom control, called Bird, which we want to drag & drop over a canvas. Here is our custom control.
1 2 3 4 5 6 7 8 9 10 11 |
<UserControl x:Class="DragAndDropProject.Bird" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" MouseLeftButtonDown="Bird_MouseLeftButtonDown" MouseLeftButtonUp="Bird_MouseLeftButtonUp" MouseMove="Bird_MouseMove" Width="100" Height="112"> <Grid x:Name="LayoutRoot" Background="Transparent"> <Image Source="Images/pigeon.png" /> </Grid> </UserControl> |
It is nothing more than a transparent image. The real work is done in the code-behind. As you see we are going to use MouseLeftButtonDown, MouseLeftButtonUp and MouseMove events:
- MouseLeftButtonDown
When the user presses the left mouse button on a bird control we indicate that he may begin a drag & drop operation. We need to save the mouse position at this moment. The next thing to do is to call the control’s CaptureMouse method in order to force capture of the mouse to it. You also may want to change the control’s cursor to Hand. - MouseLeftButtonUp
If this event is raised then the user has released the left mouse button and we have to break the drag & drop operation. We call control’s ReleaseMouseCapture method. - MouseMove
The real dragging occurs here. We first check whether we are doing drag & drop or just moving the mouse over the control. We have to calculate the difference between the mouse position, when the user has initially pressed the left button, and current position of the mouse.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
FrameworkElement item = sender as FrameworkElement; if (this.isMouseCaptured) { // Calculate the current position of the object double deltaV = e.GetPosition(null).Y - this.mousePosition.Y; double deltaH = e.GetPosition(null).X - this.mousePosition.X; double newTop = deltaV + (double)item.GetValue(Canvas.TopProperty); double newLeft = deltaH + (double)item.GetValue(Canvas.LeftProperty); Canvas parent = item.Parent as Canvas; if ((newTop + this.Height <= parent.ActualHeight) && (newTop >= 0) && (newLeft + this.Width <= parent.ActualWidth) && (newLeft >= 0)) { item.SetValue(Canvas.TopProperty, newTop); item.SetValue(Canvas.LeftProperty, newLeft); } // Update position global variable this.mousePosition = e.GetPosition(null); } |
Here isMouseCaptured indicates whether we are doing drag & drop; and mousePosition is the position of the mouse when the user has pressed the left button.
[ Online Demo ] [ Source Code ]