Dragging Element 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>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

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:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

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

About these ads

4 thoughts on “Dragging Element In A Canvas

  1. Balls, someone beat me to the comment about Josh’s DragCanvas, in fact I was just looking into it today. Playing around with getting a SnapToGrid feature up and running.

    Basics are very easy, but the way that he’s implemented it makes getting it accurate a bit more complex.

  2. sacha says:

    Ed

    I saw Joshs drag canvas thing a long time ago too. And quite right he does have simliar thing. Though I just wanted to record the mouse event code for reference, its not clever at all, I just forget it for some reason, so wanted it recorded somewhere.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s