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

Dragging Element In A Canvas

0.00/5 (No votes)
17 Jun 2009 1  
How to drag elements in a Canvas

You know when there is something you have done a million times, but for the life of you, you just can’t seem to be able to remember how to do it. Well, responding to mouse movements, is my bug bear.

Today, I had to drag an element in a container in WPF, and try as I did, I just couldn’t bend it to my will, so I went home and tried again. And this time it worked, so I am recording it for ever more, so that when I have to do this again, it will be there in 1.

The full XAML is as follows:

 1:  <Window x:Class="WpfApplication1.Window1"
 2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4:      Title="Window1" Height="300" Width="300">
 5:
 6:          <Canvas Name="canv1">
 7:              <Rectangle Canvas.Top="8" Canvas.Left="8"
 8:      Width="32" Height="32" Fill="LightPink" />
 9:              <Ellipse Canvas.Top="8" Canvas.Left="48"
10:      Width="40" Height="16" Fill="Tan" />
11:          </Canvas>
12:  </Window>

And here is the full code behind (C#):

  1:  using System;
  2:  using System.Collections.Generic;
  3:  using System.Linq;
  4:  using System.Text;
  5:  using System.Windows;
  6:  using System.Windows.Controls;
  7:  using System.Windows.Data;
  8:  using System.Windows.Documents;
  9:  using System.Windows.Input;
 10:  using System.Windows.Media;
 11:  using System.Windows.Media.Imaging;
 12:  using System.Windows.Navigation;
 13:  using System.Windows.Shapes;
 14:
 15:  namespace WpfApplication1
 16:  {
 17:      /// <summary>
 18:      /// Interaction logic for Window1.xaml
 19:      /// </summary>
 20:      public partial class Window1 : Window
 21:      {
 22:
 23:          Point startPoint;
 24:          Point selectedElementOrigins;
 25:          bool IsDragging;
 26:          UIElement selectedElement;
 27:
 28:
 29:          public Window1()
 30:          {
 31:              InitializeComponent();
 32:              canv1.PreviewMouseLeftButtonDown += Canvas_PreviewMouseLeftButtonDown;
 33:              canv1.PreviewMouseMove += Canvas_PreviewMouseMove;
 34:              canv1.PreviewMouseLeftButtonUp += Canvas_PreviewMouseLeftButtonUp;
 35:          }
 36:
 37:          /// <summary>
 38:          /// stop dragging and release mouse capture
 39:          /// </summary>

 42:          void Canvas_PreviewMouseLeftButtonUp(object sender,
 43:              MouseButtonEventArgs e)
 44:          {
 45:              if (canv1.IsMouseCaptured)
 46:              {
 47:                  IsDragging = false;
 48:                  canv1.ReleaseMouseCapture();
 49:                  e.Handled = true;
 50:              }
 51:          }
 52:
 53:          /// <summary>
 54:          /// Works out the delta for the mouse movement
 55:          /// and moves selected element by delta
 56:          /// </summary>
 57:          void Canvas_PreviewMouseMove(object sender, MouseEventArgs e)
 58:          {
 59:
 60:              if (canv1.IsMouseCaptured)
 61:              {
 62:                  //if dragging, get the delta and add it to selected
 63:                  //element origin
 64:                  if (IsDragging)
 65:                  {
 66:                      Point currentPosition = e.GetPosition(canv1);
 67:                      double elementLeft = (currentPosition.X - startPoint.X) +
 68:                          selectedElementOrigins.X;
 69:                      double elementTop = (currentPosition.Y - startPoint.Y) +
 70:                          selectedElementOrigins.Y;
 71:                      Canvas.SetLeft(selectedElement, elementLeft);
 72:                      Canvas.SetTop(selectedElement, elementTop);
 73:                  }
 74:              }
 75:          }
 76:
 77:          /// <summary>
 78:          /// Obtain start point and selected element, and record
 79:          /// selected element original point
 80:          /// </summary>
 81:          void Canvas_PreviewMouseLeftButtonDown(object sender,
 82:              MouseButtonEventArgs e)
 83:          {
 84:              //Dont act apon events from parent element
 85:              if (e.Source == canv1)
 86:                  return;
 87:
 88:              if (!IsDragging)
 89:              {
 90:                  startPoint = e.GetPosition(canv1);
 91:                  selectedElement = e.Source as UIElement;
 92:                  canv1.CaptureMouse();
 93:
 94:                  IsDragging = true;
 95:
 96:                  selectedElementOrigins =
 97:                      new Point(
 98:                          Canvas.GetLeft(selectedElement),
 99:                          Canvas.GetTop(selectedElement));
100:              }
101:              e.Handled = true;
102:          }
103:      }
104:  }

There, so now we have it for ever. Amen, here is a small demo project (VS2008).

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