Drag and Drop in Siliverlight using Mouse

Recently I started working with Silverlight. It is really a wonderful tool from Microsoft and I am too excited about it. It gives developer the power to create impressive looking user interface. In this tutorial I will focus on drag and drop functionality in Silverlight using mouse. You can download complete source code from SilverLightMouseEvents.zip.

First create a new Silverlight Application project, here is how your project will look like:-



I have added event handlers for MouseLeftButtonDown,MouseLeftButtonUp,MouseMove and LostMouseCapture. I also added a canvax and a button in MainPage.xaml. Here is the code of MainPage.xaml after adding events:-

<UserControl x:Class="SliverLightMouseEvents.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="491" 
             MouseLeftButtonDown="UserControl_MouseLeftButtonDown" 
             MouseLeftButtonUp="UserControl_MouseLeftButtonUp" 
             MouseMove="UserControl_MouseMove" 
             LostMouseCapture="UserControl_LostMouseCapture">

    <Canvas x:Name="mainCanvas" Width="640" Height="480" >
        <Button Content="AddRectangle" Width="100" Height="30" Margin="12,258,378,12" Click="Button_Click" />
    </Canvas>
</UserControl>

On the button click I have added a rectangle to mainCanvas. Here is how it is done:-

private void Button_Click(object sender, RoutedEventArgs e)
{
    //Creating a rectangle
    Rectangle rectangle = new Rectangle()
    {
        Stroke = new SolidColorBrush(Colors.Black),
        Width = 100,
        Height = 100,
        Fill = new SolidColorBrush { Color = Color.FromArgb(200, 146, 5, 23) }
    };


    //Set its initial position
    Canvas.SetLeft(rectangle, 100);
    Canvas.SetTop(rectangle, 100);

    //Adding it to mainCanvas
    mainCanvas.Children.Add(rectangle);
}

Now first we have to handle MouseLeftButtonDown event. Here is the code:-

private void UserControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    //If mouse button is down and control on which button is pressed is rectangle
    if (e.OriginalSource.GetType() == typeof(Rectangle))
    {
        this.isMoving = true;

        //Calculate the current mouse's relative position
        clickOffset.X = e.GetPosition(mainCanvas).X - Canvas.GetLeft((Rectangle)e.OriginalSource);
        clickOffset.Y = e.GetPosition(mainCanvas).Y - Canvas.GetTop((Rectangle)e.OriginalSource);

        //Generate Mouse Events even if mouse is moved outside control's area
        CaptureMouse();
    }
}

One thing which you should remember when doing drag and drop is CaptureMouse() function. Many user will move their mouse outside your application while draging and if you do not write CaptureMouse() when mouse is outside you will recieve no events from mouse.

Now here is the code which I wrote in MouseMove event:-
private void UserControl_MouseMove(object sender, MouseEventArgs e)
{
    if (this.isMoving) //If mouse button is down
    {
        if (e.OriginalSource is Rectangle) //if control is rectangle
        {
            Rectangle rect = e.OriginalSource as Rectangle; //Get the original control

            //Changing its color so we can get the feel of selection
            rect.Fill = new SolidColorBrush { Color = Color.FromArgb(100, 146, 5, 23) };

            //Calculate the distance form initial mouse down and adjust top,left accordingly
            Canvas.SetLeft(rect, e.GetPosition(mainCanvas).X - clickOffset.X);
            Canvas.SetTop(rect, e.GetPosition(mainCanvas).Y - clickOffset.Y);
        }
    }
}

In above code, I adjusted the top,left of the Rectangle as per position of mouse.

Now when user release the mouse button, MouseLeftButtonUp event is fired. Here is the code which I written in MouseLeftButtonUp event:-

private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    //if mouse is moving
    if (this.isMoving)
    {
        //if control is rectangle on which mouse is moving
        if (e.OriginalSource is Rectangle)
        {
            //Change rectangle color back to normal
            Rectangle rect = e.OriginalSource as Rectangle;
            rect.Fill = new SolidColorBrush { Color = Color.FromArgb(200, 146, 5, 23) };
        }
        //Set moving to false
        this.isMoving = false;

        //Stop listening mouse events which are outside current control's boundary
        ReleaseMouseCapture();
    }
}

Finally here is the code of LostMouseCapture event, if you remove this code from my sample, it will behave weired when mouse goes outside control's area:-

private void UserControl_LostMouseCapture(object sender, MouseEventArgs e)
{
    if (this.isMoving)// if Previously mouse is clicked down
    {
        this.isMoving = false; //mark that mouse is now moved up
    }
}

Finally here is the output of the application:-