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

WPF Draggable Label

0.00/5 (No votes)
13 Apr 2010 1  
WPF label control that can be dragged and resized at runtime
Test1.jpg Test2.jpg

Introduction

This article shows how to implement a WPF label control that can be dragged and resized at runtime. Even though the current implementation is done based on the WPF label control, with a small amount of modifications, the code and logic here should be able to be reused for making any WPF control draggable and resizable at runtime.

Description

Most of the code for the draggable label is self explanatory. The core concept used for achieving the dragging effect is explained below.

To implement the runtime drag functionality, basically we need two pieces of information - the previous location of the mouse and the current location of the mouse. Using that information, the distance the control was dragged can be calculated. Therefore at the beginning of each mouse move event, the current location of the mouse is captured and assigned to the previous location at the end of the mouse move event.

protected override void OnMouseMove(MouseEventArgs e)
{
    Window wnd = Window.GetWindow(this);
    Point currentLocation = e.MouseDevice.GetPosition(wnd);    

    ...
    ...
    ...

    _previousLocation = currentLocation;
}

In WPF, a position of a control can be changed by applying a TranslateTransform to it. The delta TranslateTransform can be calculated within the mouse move event using the previous mouse location and the current mouse location. But when applying the TranslateTransform for the drag delta, we have to be careful not to destroy any existing transforms applied to the draggable label. Therefore a TransformGroup with the previous transform and the drag delta will be created and applied.

var delta = new TranslateTransform
    (currentLocation.X - _previousLocation.X, currentLocation.Y - _previousLocation.Y);

var group = new TransformGroup();
group.Children.Add(_previousTransform);
group.Children.Add(delta);

this.RenderTransform = group;
_ previousTransform = this.RenderTransform;

In addition to the events and properties inherited from the WPF label control, the draggable label control exposes two additional events.

  • Drag
  • Resize

Drag

Fired when the control is being dragged. DraggableLabelDragEventArgs are passed in as event arguments. The DraggableLabelDragEventArgs exposes the following properties:

  • X – Current horizontal position of the draggable label
  • Y – Current vertical position of the draggable label

Resize

Fired when the control is being resized. DraggableLabelResizeEventArgs are passed in as event arguments. The DraggableLabelResizeEventArgs exposes the following properties:

  • Width – Current width of the draggable label
  • Height – Current height of the draggable label

Usage

The draggable label can be added to any container similarly to any other WPF user control. In Visual Studio 2008, right click on the Toolbox and click “Choose Items...”. In the Choose Toolbox Items dialog box, go to the WPF Components tab. Browse for the RtwControls.DraggableLabel.dll assembly and click Open. The draggable label control will be added to the WPF Components list. Click OK to close the toolbox items dialog and add the draggable label control to the Toolbox. Now the draggable label can be dragged and dropped from the toolbox.

Alternatively, you can also manually add a reference to the RtwControls.DraggableLabel.dll assembly from your WPF project and use the namespace for the draggable label as indicated below.

<Window x:Class="DraggableLabelTest.LayoutWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:rtw="clr-namespace:RtwControls;assembly=RtwControls.DraggableLabel"
    Title="Layout" Height="403" Width="836">
    <Grid>
        <rtw:DraggableLabel BorderBrush="Black" BorderThickness="1" 
                    HorizontalAlignment="Left" Margin="12,12,0,0" Name="Label1" 
                    OverridesDefaultStyle="False" Drag="draggableLabel_Drag" 
                    Resize="draggableLabel_Resize" 
                    VerticalAlignment="Top">Label1</rtw:DraggableLabel>
    </Grid>
</Window>

Demo Application

The demo application shows how to implement a customizable print layout using the draggable label control. The main window contains the fields whose data will be printed according to the custom layout.

MainWindow.jpg

From the layout window, the user can customize the print layout by dragging and resizing the draggable labels. Once saved, the custom locations will be saved in the "layout.xml" file.

Layout.jpg

While printing, the saved locations will be loaded from the "layout.xml" file and the data will be printed at the appropriate positions.

PrintPreview.jpg

History

  • April 13, 2010: First release

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