Dragging Element In A Canvas





0/5 (0 vote)
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).