#688 – Moving an Element with the Mouse
November 12, 2012 3 Comments
Here’s a short example that uses the MouseDown, MouseMove and MouseUp events to move a user interface element around on the screen. We place a Label in a Canvas and then bind its position to a couple of properties that keep track of the desired X and Y position of the label. The properties derive from a base position for the label, plus the current mouse position.
Here’s the XAML:
<Canvas> <Label Content="Feast" Background="ForestGreen" Padding="12,7" Canvas.Left="{Binding XPosition}" Canvas.Top="{Binding YPosition}" MouseDown="Feast_MouseDown" MouseUp="Feast_MouseUp" MouseMove="Feast_MouseMove"/> </Canvas>
And the code:
public partial class MainWindow : Window, INotifyPropertyChanged { public MainWindow() { InitializeComponent(); this.DataContext = this; } private Point BasePoint = new Point(0.0, 0.0); private double DeltaX = 0.0; private double DeltaY = 0.0; private bool moving = false; private Point PositionInLabel; public double XPosition { get { return BasePoint.X + DeltaX; } } public double YPosition { get { return BasePoint.Y + DeltaY; } } private void Feast_MouseDown(object sender, MouseButtonEventArgs e) { Label l = e.Source as Label; if (l != null) { l.CaptureMouse(); moving = true; PositionInLabel = e.GetPosition(l); } } private void Feast_MouseMove(object sender, MouseEventArgs e) { if (moving) { Point p = e.GetPosition(null); DeltaX = p.X - BasePoint.X - PositionInLabel.X; DeltaY = p.Y - BasePoint.Y - PositionInLabel.Y; RaisePropertyChanged("XPosition"); RaisePropertyChanged("YPosition"); } } private void Feast_MouseUp(object sender, MouseButtonEventArgs e) { Label l = e.Source as Label; if (l != null) { l.ReleaseMouseCapture(); BasePoint.X += DeltaX; BasePoint.Y += DeltaY; DeltaX = 0.0; DeltaY = 0.0; moving = false; } } public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string prop) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(prop)); } }
Pingback: Dew Drop–November 12, 2012 (#1,441) | Alvin Ashcraft's Morning Dew
I’ve spent HOURS looking for this capability and your post is the best one by far. However, it only works if the label is at (0,0) on the canvas. I think the line private Point BasePoint = new Point(0.0, 0.0); has to be modified to set BasePoint to the current location of the label. How can that be done?
Thanks! I think you could probably capture the current position in the MouseDown event. Good catch.