Posted By

cabrel on 09/08/10


Tagged

c drop drag WPF


Versions (?)

Who likes this?

2 people have marked this snippet as a favorite

galofre
Tyster


Drag & Drop with WPF in C#


 / Published in: C#
 

  1. // WPF Canvas Object
  2. // Canvas LayoutCanvas;
  3. //
  4. // Events Required
  5. //
  6. // Canvas_PreviewMouseLeftButtonDown
  7. // Canvas_PreviewMouseMove
  8. // Canvas_PreviewMouseLeftButtonUp
  9. // Parent_PreviewKeyDown
  10. //
  11. // LayoutCanvas.PreviewMouseLeftButtonDown += LayoutCanvas_PreviewMouseLeftButtonDown;
  12. // LayoutCanvas.PreviewMouseMove += LayoutCanvas_PreviewMouseMove;
  13. // LayoutCanvas.PreviewMouseLeftButtonUp += LayoutCanvas_PreviewMouseLeftButtonUp;
  14. // WindowOrPage.PreviewKeyDown += WindowOrPage_PreviewKeyDown;
  15. //
  16. // Parameters Required
  17. //
  18. // For capturing the mouse position:
  19. // Point ddStartPoint;
  20. //
  21. // The top left corner of the child object (left = x, top = y)
  22. // double ddOriginalLeft;
  23. // double ddOriginalTop;
  24. //
  25. // Properties for managing the state of the drag & drop process:
  26. // bool ddIsMouseDown;
  27. // bool ddIsBeingDragged;
  28. //
  29. // Our original UI element (in my case the children are all Image objects)
  30. // UIElement ddOriginalElement;
  31. //
  32. // The container of the above element when we are in dragging mode
  33. // System.Windows.Shapes.Rectangle ddOverlay;
  34. //
  35.  
  36. //
  37. // Canvas_PreviewMouseLeftButtonDown
  38. //
  39. // We assign this to our Canvas object as it will control
  40. // catching whether or not we are clicking on the canvas itself
  41. // or on one of its children
  42. //
  43. private void LayoutCanvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  44. {
  45. // If the source of the click is our canvas object then we want
  46. // to exit because we are looking for it's children to drag
  47. // and not the canvas itself.
  48. if(e.Source == LayoutCanvas)
  49. {
  50. return;
  51. }
  52.  
  53. // Identifies that we have started dragging
  54. ddIsMouseDown = true;
  55.  
  56. // Captures the mouse position in the layout canvas
  57. ddStartPoint = e.GetPosition(LayoutCanvas);
  58.  
  59. // Sets up our element that we will be dragging
  60. ddOriginalElement = (UIElement)e.Source;
  61.  
  62. // Tells the Window to give the mouse to the LayoutCanvas
  63. // object.
  64. LayoutCanvas.CaptureMouse();
  65.  
  66. e.Handled = true;
  67. }
  68.  
  69. //
  70. // Canvas_PreviewMouseMove
  71. //
  72. // Our event handler for updating the position of our
  73. // dragged element
  74. //
  75. // This introduces two helper methods DragStarted() and DragMoved()
  76. // They will be covered later on in the code.
  77. //
  78. private void LayoutCanvas_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
  79. {
  80. if(ddIsMouseDown)
  81. {
  82. if(!ddIsBeingDragged)
  83. {
  84. // Capture our mouse position relative to the LayoutCanvas object
  85. var mousePosition = e.GetPosition(LayoutCanvas);
  86.  
  87. // Creates a transparent rectangle around our current drag point and we want to
  88. // check here that we are within that rectangle
  89. if(Math.Abs(mousePosition.X - ddStartPoint.X) > SystemParameters.MinimumHorizontalDragDistance &&
  90. Math.Abs(mousePosition.Y - ddStartPoint.Y) > SystemParameters.MinimumVeritcalDragDistance)
  91. {
  92. DragStarted();
  93. }
  94. }
  95. else
  96. {
  97. DragMoved();
  98. }
  99. }
  100. }
  101.  
  102. //
  103. // Canvas_PreviewMouseLeftButtonUp
  104. //
  105. // Controls the functionality for finishing our drag and drop process.
  106. // This will also introduce the call to DragFinished(bool state);
  107. //
  108. private void LayoutCanvas_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
  109. {
  110. // This is a fairly simple check. If we are still dragging
  111. // or starting to drag which means ddIsMouseDown would be 'True'
  112. // then we don't stop the drag
  113. if(ddIsMouseDown)
  114. {
  115. DragFinished(false);
  116. }
  117. }
  118.  
  119. //
  120. // Page_PreviewKeydown
  121. //
  122. // In my code I have my canvas in a Page, you can do this with a Window object as well.
  123. //
  124. private void Page_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
  125. {
  126. if(e.Key == Key.Escape && ddIsBeingDragged)
  127. {
  128. DragFinished = true;
  129. }
  130. }
  131.  
  132. // Helper Methods
  133.  
  134. //
  135. // DragStarted()
  136. //
  137. //
  138. private void DragStarted()
  139. {
  140. // Capture our last remaining properties
  141. // needed to support our drag and drop
  142. // process
  143. ddIsBeingDragged = true;
  144. ddOriginalLeft = Canvas.GetLeft(ddOriginalElement);
  145. ddOriginalTop = Canvas.GetTop(ddOriginalElement);
  146.  
  147. // What we are doing here is creating a semi-transparent
  148. // mirror image of the object we are dragging.
  149. //
  150. // This allows us to visually see that we have selected
  151. // an object and are dragging it.
  152. var brush = new VisualBrush(ddOriginalElement);
  153. brush.Opacity = 0.5;
  154.  
  155. ddOverlay = new System.Windows.Shapes.Rectangle();
  156. ddOverlay.Width = ddOriginalElement.RenderSize.Width;
  157. ddOverlay.Height = ddOriginalElement.RenderSize.Height;
  158. ddOverlay.Fill = brush;
  159.  
  160. // Finally add the overlay to the LayoutCanvas for displaying
  161. LayoutCanvas.Children.Add(ddOverlay);
  162. }
  163.  
  164.  
  165. //
  166. // DragMoved();
  167. //
  168. private void DragMoved()
  169. {
  170. // Capture the current mouse position, this will be used
  171. // to redraw the overlay element we created in DragStarted()
  172. var currentPosition = System.Windows.Input.Mouse.GetPosition(LayoutCanvas);
  173. var elementLeft = (currentPosition.X - ddStartPoint.X) + ddOriginalLeft;
  174. var elementTop = (currentPosition.Y - ddStartPoint.Y) + ddOriginalTop;
  175.  
  176. // We update the overlay's position on the LayoutCanvas
  177. // by setting it's top left corner position below
  178. Canvas.SetLeft(ddOverlay, elementLeft);
  179. Canvas.SetTop(ddOverlay, elementTop);
  180. }
  181.  
  182. //
  183. // DragFinished();
  184. //
  185. private void DragFinished(bool canceled)
  186. {
  187. if(ddOverlay != null)
  188. {
  189. // capture our current position
  190. var topLeft = Canvas.GetLeft(ddOverlay);
  191. var top = Canvas.GetTop(ddOverlay);
  192.  
  193. if(ddIsBeingDragged)
  194. {
  195. LayoutCanvas.Children.Remove(ddOverlay);
  196.  
  197. // If it wasn't prematurely canceled, then
  198. // move the element to the current mouse position
  199. if(!canceled)
  200. {
  201. Canvas.SetLeft(ddOriginalElement, topLeft);
  202. Canvas.SetTop(ddOriginalElement, top);
  203. }
  204.  
  205. // Release the mouse from the layoutcanvas.
  206. // This is very important. If you do not release the mouse
  207. // you have to set the focus of the mouse to another application
  208. // and then back again to regain mouse control
  209. LayoutCanvas.ReleaseMouseCapture();
  210.  
  211. // Reset our drag & drop properties
  212. ddOverlay = null;
  213. ddIsMouseBeingDragged = false;
  214. ddIsMouseDown = false;
  215. }
  216. }
  217. }

Report this snippet  

Comments

RSS Icon Subscribe to comments
Posted By: cabrel on November 17, 2010

http://blog.zerklabs.com/2010/09/wpf-drag-and-drop/

You need to login to post a comment.