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: 18: 19: 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: 38: 39:
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: 54: 55: 56: 57: void Canvas_PreviewMouseMove(object sender, MouseEventArgs e)
58: {
59:
60: if (canv1.IsMouseCaptured)
61: {
62:
63:
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: 78: 79: 80: 81: void Canvas_PreviewMouseLeftButtonDown(object sender,
82: MouseButtonEventArgs e)
83: {
84:
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).