Click here to Skip to main content
15,867,330 members
Articles / Desktop Programming / WPF

WPF Draggable Label

Rate me:
Please Sign up or sign in to vote.
4.63/5 (16 votes)
13 Apr 2010CPOL3 min read 62.2K   6.3K   42   10
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.

C#
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.

C#
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.

XML
<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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionDrag Horizontal only Pin
Mahesh Sanika19-Mar-15 20:08
Mahesh Sanika19-Mar-15 20:08 
AnswerRe: Drag Horizontal only Pin
Rajitha Wimalasooriya20-Mar-15 22:45
Rajitha Wimalasooriya20-Mar-15 22:45 
GeneralRe: Drag Horizontal only Pin
Mahesh Sanika22-Mar-15 20:05
Mahesh Sanika22-Mar-15 20:05 
GeneralMy vote of 5 Pin
AldertNagel17-Mar-13 9:01
AldertNagel17-Mar-13 9:01 
QuestionSave Layout Pin
Jay Sinha19-Jul-11 23:19
Jay Sinha19-Jul-11 23:19 
GeneralGood Work Pin
anthride8-Jun-11 6:54
anthride8-Jun-11 6:54 
GeneralMy vote of 5 Pin
Bill SerGio, The Infomercial King21-May-11 2:41
Bill SerGio, The Infomercial King21-May-11 2:41 
GeneralVote 5 Pin
eric_yu4-May-11 10:19
eric_yu4-May-11 10:19 
GeneralMy vote of 2 Pin
tec-goblin21-Apr-10 3:23
tec-goblin21-Apr-10 3:23 
GeneralRe: My vote of 2 Pin
cwp4221-Apr-10 22:02
cwp4221-Apr-10 22:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.