Click here to Skip to main content
13,150,178 members (57,491 online)
Click here to Skip to main content
Add your own
alternative version

Stats

2.8K views
103 downloads
2 bookmarked
Posted 5 Jan 2017

Draggable Popup

, 5 Jan 2017
Rate this:
Please Sign up or sign in to vote.
This is a simple popup that includes drag capability. The code should be helpful to anyone looking to create a control drag capability.

Introduction

I was asked to put up a dialog while the application was busy that could be dragged, allowing the user to move it out of the way so that he could see what was underneath.

Background

I had tried several things I found online but did not really like any of them, and some actually had issues.

The Code

The DraggablePopup derives from the Popup class. The overridden OnInitialized method checks that the Popup has content. This is because the Popup cannot be clicked on. The content, or Child, should contain a FrameworkElement that encompases any part of the Popup that the designer wants to allow the user to click and drag with. The OnInitialized method, after checking that there is content, then attaches handlers for the MouseLeftButtonDown, MouseLeftButtonUp and MouseMove events:

public class DraggablePopup : Popup
{
 Point _initialMousePosition;
 bool _isDragging ;

 protected override void OnInitialized(EventArgs e)
 {
  var contents = Child as FrameworkElement;
  Debug.Assert(contents != null, "DraggablePopup either has no content if content that " +
   "does not derive from FrameworkElement. Must be fixed for dragging to work.");
  contents.MouseLeftButtonDown += Child_MouseLeftButtonDown;
  contents.MouseLeftButtonUp += Child_MouseLeftButtonUp;
  contents.MouseMove += Child_MouseMove;
 }

 private void Child_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
 {
  var element = sender as FrameworkElement;
  _initialMousePosition = e.GetPosition(null);
  element.CaptureMouse();
  _isDragging = true;
  e.Handled = true;
 }

 private void Child_MouseMove(object sender, MouseEventArgs e)
 {
  if (_isDragging)
  {
   var currentPoint = e.GetPosition(null);
   HorizontalOffset = HorizontalOffset + (currentPoint.X - _initialMousePosition.X);
   VerticalOffset = VerticalOffset + (currentPoint.Y - _initialMousePosition.Y);
  }
 }

 private void Child_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
 {
  if (_isDragging)
  {
   var element = sender as FrameworkElement;
   element.ReleaseMouseCapture();
   _isDragging = false;
   e.Handled = true;
  }
 }
}

There are two private fields: one to indicate that a drag operation is in progress, and the other to contain the initial location that dragging started. The MouseLeftButtonDown and MouseLeftButtonUp event handlers basically start and end the process by setting the bool IsDragging field, and the MouseLeftButtonDown also sets the initial location of the click. Then the MouseMove adjusts the location of the Popup.

Using the Code

I have used a Border as the content in the sample. There is a Button within the Border that allows the Popup to be closed, but is not shown in the code below. I have set the Placement as Center to the containing Window. From my experience, the way Placement works is different on a Window than other controls. In other controls, to get the Popup centered, I had to use the HorzontalOffset and VerticalOffset since the top left corner is what is centered.

<local:DraggablePopup Width="300"
                      Height="200"
                      IsOpen="{Binding ElementName=WindowToggleButton,
                                       Path=IsChecked}"
                      Placement="Center"
                      PlacementTarget="{Binding RelativeSource={RelativeSource AncestorType=Window}}"
                     >
 <Border Background="LightGray"
         BorderBrush="Black"
         BorderThickness="1" >
  </Border>
</local:DraggablePopup>

History

  • 2016/12/23: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Clifford Nelson
Software Developer (Senior) Clifford Nelson Consulting
United States United States
Has been working as a C# developer on contract for the last several years, including 3 years at Microsoft. Previously worked with Visual Basic and Microsoft Access VBA, and have developed code for Word, Excel and Outlook. Started working with WPF in 2007 when part of the Microsoft WPF team. For the last eight years has been working primarily as a senior WPF/C# and Silverlight/C# developer. Currently working as WPF developer with BioNano Genomics in San Diego, CA redesigning their UI for their camera system. he can be reached at qck1@hotmail.com.

You may also be interested in...

Pro

Comments and Discussions

 
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170924.2 | Last Updated 5 Jan 2017
Article Copyright 2017 by Clifford Nelson
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid