Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Silverlight Drag and Drop Custom Controls

0.00/5 (No votes)
25 Oct 2008 3  
How to create Custom Control and Drag and Drop Functionality

Introduction

Everything started in a Microsoft Event where I was able to view the Coolness of the Digg Sample when this was neither on the web and Silverlight beta 1 and beta 2 were coming.

I personally believe that RIA (Rich Internet Applications) is becoming the Windows on the Web, and these are the reasons why:

  • In Silverlight, you are working on the Client Environment and don't have postbacks.
  • In Silverlight, you can animate the user interaction like a WPF application.
  • In Silverlight, you can create a control that is customizable by Application Styles, I know this sounds like CSS but it goes to a different level.

Using the Code

The Drag Control is a Control based from the User Control that provides the user the ability to forget about setting the Mouse Capture events in his code.

public class DragControl : UserControl
{
    private bool _isMouseDown;
    private Point _lastPosition;
    int zIndex = 0;

Note the Extra variables that will help you on the events since we don't want to redo everything over and over especially if we don't need it. Then you will need the events of the Mouse, on the Mouse Down you should be able to detect it and place your control on top of any other control, I've used a BringToFront() method that will help me perform this action.

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
    _isMouseDown = true;
    BringToFront();
    this.CaptureMouse();
    _lastPosition = e.GetPosition(Application.Current.RootVisual);
    base.OnMouseLeftButtonDown(e);
}

Now that we have the Button Down, we need the Up event. This is pretty easy since we just need to say stop here and not continue any action.

protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
    _isMouseDown = false;
    zIndex = 0;
    this.ReleaseMouseCapture();
    base.OnMouseLeftButtonUp(e);
}

And finally we will need the MouseMouse event. This is the one that handles the motion of the control.

protected override void OnMouseMove(MouseEventArgs e)
{
    if (_isMouseDown)
    {
        Point currentPosition = e.GetPosition(Application.Current.RootVisual);
        Canvas.SetLeft(this, currentPosition.X);
        Canvas.SetTop(this, currentPosition.Y);
        _lastPosition = currentPosition;
    }
    base.OnMouseMove(e);
}

Also important is our BringToFront() function that will help you give that Windows functionality when you click to bring to front. Please note that my Main Control is a Canvas, this is why I convert the Parent as Canvas.

protected void BringToFront()
{
    if (zIndex == 0)
    {
        var oldIndex = this.zIndex;
        var mainCanvas = this.Parent as Canvas;
        foreach (FrameworkElement fElement in mainCanvas.Children)
        {
            Canvas.SetZIndex(fElement, 0);
        }
        Canvas.SetZIndex(this, 2);
        zIndex = 1;
    }

Points of Interest

You will find that the BringtoFront method will let you do the work only if the Parent is a Canvas. The funny part is that if you are using Stack Panels or Grid, then you will have to do this work.

The canvas is the perfect example since this allows to position controls using left and top attributes.

Note: Due to some reason when compiling for the first time, VS2008 generates the code behind (file name with extension .g.cs). Please make sure you do change the base class declared here in order to make it work.

History

  • 25th October, 2008: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here