Making any User Control Draggable in Silverlight


1.gif 

Introduction

Silverlight gives you easy access to make your User Controls come alive. For example you can make any control in Silverlight draggable.  Here's how:

In your  XAML Code add a TranslateTransform inside your layout grid of your user control.  The TranslateTransform will allow you to move your grid along the x and y coordinates of your application 

Listing 1 - Adding the TranslateTransform to your control

<Grid x:Name="LayoutRoot" >
        <Grid.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform/>
                <TranslateTransform x:Name="LocalTranslateTransform"/>
            </TransformGroup>
        </Grid.RenderTransform>

Now we want to pick a control inside the UserControl to grab onto.  In our sample we will use a Border control.  Inside the Border control, we'll add mouse events to handle the various states of dragging with the mouse.

Listing 2 - Hooking up the mouse events to the Border control

<Border x:Name="myToolbar" MouseLeftButtonDown="OnToolbarClicked" MouseLeftButtonUp="OnToolbarReleased" MouseMove="OnToolbarMoving"  />

The Code

The XAML part was pretty simple.  Now let's look at the code behind.  All of the dragging functionality is handled by our 3 event handlers: OnToolbarClicked, OnToolbarReleased, and OnToolbarMoving.  When we first click down on the border control, we need to record the initial offset point for our transform.  We also need to set the state to mouseDownInToolbar to true to indicate we are dragging.  Finally we need to set the mouse mode to capturing inside the border control.

Listing 3 - Handling the mousedown event inside the border

private void OnToolbarClicked(object sender, MouseButtonEventArgs e)
{
    mouseDownInToolbar = true;
    DragOffset = e.GetPosition(LayoutRoot);
    toolbarBorder.CaptureMouse();
}

While the mouse is in the mouseDownInToolbar state, we need to translate the position of the toolbar in reference to the position of the mouse.  Listing 4 illustrates how we go about this.  We get the position of the mouse relative to the main grid of the control.  Then we change the TranslateTransform of the grid based on the new position of the mouse.  We also need to offset the current mouse position by the original location of the mouse when we first clicked down in the control.  Everytime we move the mouse, the new TranslateTransform will be computed and our control will move to the translated location.  The mouse cursor will remain at the point when we first clicked the toolbar.

Listing 4 - handling the dragging of the control while the mouse is moving

private void OnToolbarMoving(object sender, MouseEventArgs e)
{
    if (mouseDownInToolbar)
    {
        // we want to move it based on the position of the mouse
        moveUserControl(e);
    }
}

private void moveUserControl (MouseEventArgs e)
{
    Point mousePos = e.GetPosition(LayoutRoot);
    Double newX = LocalTranslateTransform.X + (mousePos.X - DragOffset.X);
    Double newY = LocalTranslateTransform.Y + (mousePos.Y - DragOffset.Y);
    LocalTranslateTransform.X = newX;
    LocalTranslateTransform.Y = newY;
}

When the user unclicks the mouse, we need to stop the drag process.  The MouseUp event handler will release the mouse capture and set the mouseDownInToolbar state to false.  This will prevent the toolbar to continue to move as we drag the mouse around the screen.

Listing 5 - Handling Mouse Up when dragging the Toolbar

private void OnToolbarReleased(object sender, MouseButtonEventArgs e)
{
    mouseDownInToolbar = false;
    toolbarBorder.ReleaseMouseCapture();
}

Conclusion

Manipulating size and position of controls is fairly easy in Silverlight with the power of transforms. Dragging a control is accomplished using the TranslateTransform in conjunction with mouse events and functions.  You can probably take this a step further and build your own docking framework. Anyway, drag yourself away from conventional controls in Windows and enjoy the power and flexibility of WPF in the browser with Silverlight.


Similar Articles