This example shows how you can let the user move and resize a Rectangle object at run time in a WPF program. The program’s XAML code defines a Canvas object that contains the Rectangle. The program catches the Canvas object’s MouseDown, MouseMove, and MouseUp events. One oddity of this is that the Canvas must have a non-null background to make it generate mouse events. In this example, I set its background to Transparent so it’s still invisible, but it’s not null.
The program uses the following code to track the resizing operation.
// The part of the rectangle the mouse is over. private enum HitType { None, Body, UL, UR, LR, LL }; // The part of the rectangle under the mouse. HitType MouseHitType = HitType.None; // True if a drag is in progress. private bool DragInProgress = false; // The drag's last point. private Point LastPoint;
The HitType enumeration indicates parts of the rectangle. The variable MouseHitType indicates the part of the rectangle under the mouse at various times. The variable DragInProgress is true when the user is moving or resizing the rectangle. LastPoint is the last recorded position of the mouse during a drag.
The program uses two helper methods. The SetHitType method shown in the following code returns a HitType value to indicate what part of the rectangle is below the mouse.
// Return a HitType value to indicate what is at the point. private HitType SetHitType(Rectangle rect, Point point) { double left = Canvas.GetLeft(rectangle1); double top = Canvas.GetTop(rectangle1); double right = left + rectangle1.Width; double bottom = top + rectangle1.Height; if (point.X < left) return HitType.None; if (point.X > right) return HitType.None; if (point.Y < top) return HitType.None; if (point.Y > bottom) return HitType.None; const double GAP = 10; if (point.X - left < GAP) { // Left edge. if (point.Y - top < GAP) return HitType.UL; if (bottom - point.Y < GAP) return HitType.LL; return HitType.L; } else if (right - point.X < GAP) { // Right edge. if (point.Y - top < GAP) return HitType.UR; if (bottom - point.Y < GAP) return HitType.LR; return HitType.R; } if (point.Y - top < GAP) return HitType.T; if (bottom - point.Y < GAP) return HitType.B; return HitType.Body; }
This method uses the Canvas class's GetLeft and GetTop methods to get the rectangle's left and top coordinates. (The example assumes you set those values for the rectangle.) Those are attached properties provided by the Canvas control for the Rectangle control, so you need to use the Canvas control's methods to get and set their values.
The code first compares the left and top values to the rectangle's edges. If the mouse lies outside of the rectangle, the method returns None.
Next the code uses the mouse's coordinates and the rectangle's coordinates to decide whether the mouse is over a rectangle corner, edge, or body, and it returns the correct HitType.
The following code shows the SetMouseCursor helper method.
// Set a mouse cursor appropriate for the current hit type. private void SetMouseCursor() { // See what cursor we should display. Cursor desired_cursor = Cursors.Arrow; switch (MouseHitType) { case HitType.None: desired_cursor = Cursors.Arrow; break; case HitType.Body: desired_cursor = Cursors.ScrollAll; break; case HitType.UL: case HitType.LR: desired_cursor = Cursors.SizeNWSE; break; case HitType.LL: case HitType.UR: desired_cursor = Cursors.SizeNESW; break; case HitType.T: case HitType.B: desired_cursor = Cursors.SizeNS; break; case HitType.L: case HitType.R: desired_cursor = Cursors.SizeWE; break; } // Display the desired cursor. if (Cursor != desired_cursor) Cursor = desired_cursor; }
This code simply sets the cursor that is appropriate for the mouse's hit type.
The following code executes when the user presses the mouse down over the Canvas.
// Start dragging. private void canvas1_MouseDown(object sender, MouseButtonEventArgs e) { MouseHitType = SetHitType(rectangle1, Mouse.GetPosition(canvas1)); SetMouseCursor(); if (MouseHitType == HitType.None) return; LastPoint = Mouse.GetPosition(canvas1); DragInProgress = true; }
This method calls SetHitType to see whether the mouse is over the rectangle. If it is not, the method returns.
Otherwise the method saves the mouse's current location in the LastPoint variable and sets DragInProgress to true.
When the user moves the mouse, the following code executes.
// If a drag is in progress, continue the drag. // Otherwise display the correct cursor. private void canvas1_MouseMove(object sender, MouseEventArgs e) { if (DragInProgress) { // See how much the mouse has moved. Point point = Mouse.GetPosition(canvas1); double offset_x = point.X - LastPoint.X; double offset_y = point.Y - LastPoint.Y; // Get the rectangle's current position. double new_x = Canvas.GetLeft(rectangle1); double new_y = Canvas.GetTop(rectangle1); double new_width = rectangle1.Width; double new_height = rectangle1.Height; // Update the rectangle. switch (MouseHitType) { case HitType.Body: new_x += offset_x; new_y += offset_y; break; case HitType.UL: new_x += offset_x; new_y += offset_y; new_width -= offset_x; new_height -= offset_y; break; case HitType.UR: new_y += offset_y; new_width += offset_x; new_height -= offset_y; break; case HitType.LR: new_width += offset_x; new_height += offset_y; break; case HitType.LL: new_x += offset_x; new_width -= offset_x; new_height += offset_y; break; case HitType.L: new_x += offset_x; new_width -= offset_x; break; case HitType.R: new_width += offset_x; break; case HitType.B: new_height += offset_y; break; case HitType.T: new_y += offset_y; new_height -= offset_y; break; } // Don't use negative width or height. if ((new_width > 0) && (new_height > 0)) { // Update the rectangle. Canvas.SetLeft(rectangle1, new_x); Canvas.SetTop(rectangle1, new_y); rectangle1.Width = new_width; rectangle1.Height = new_height; // Save the mouse's new location. LastPoint = point; } } else { MouseHitType = SetHitType(rectangle1, Mouse.GetPosition(canvas1)); SetMouseCursor(); } }
This code does one of two things depending on whether a drag is in progress.
If a drag is not in progress, the method calls SetHitType to see whether the mouse is over the rectangle and SetMouseCursor to display an appropriate cursor.
If a drag is in progress, the code gets the mouse's current position and subtracts its coordinates from LastPoint to see how far the mouse has moved since that point was recorded. It gets the rectangle's current position, and then initializes variables to hold the rectangle's new size and position.
Then depending on the part of the rectangle that was under the mouse, the method updates the rectangle's new size and position.
The method ensures that the rectangle's new width and height aren't less than 0, and it updates the rectangle's size and position. Finally the code saves the mouse's current location for next time.
The following code shows the last piece of the program.
// Stop dragging. private void canvas1_MouseUp(object sender, MouseButtonEventArgs e) { DragInProgress = false; }
This code simply stops the drag.




Love your work… again!
I need to get a good sample for blinking Label in WPF, have you any article for that subject?
See this example:
Make a blinking label in WPF and C#
Thanks for referencing that. I’ll make a try with it.
Thanks a lot Sir, It works fine. I used that.
I just wanted to thank you for posting this. I was trying to figure out how to do this exact same thing (except I needed the user to draw the rectangle first) and this helped me out immensely. As a novice programmer, I have been struggling with trying to figure this out for a long time since I had to start from scratch but your code was so simple it allowed me to incorporate it into what I am doing very easily.
Thanks again.
Sir, I need to move a small rectangle box over a curved surface in c# in visual studio 2008. Am new to C#. Actually that box would be a train and the curved path a track.
WPF’s animations can do this. Unfortunately they’re kind of complicated. Download this example:
I’ll post a description of it when I have a chance
Hello,
thanks and good job, It was a good inspiration; though I factorized the code and I put the events over the rectangle, so I can build a custom control and edit several rectangle without all the code behind mess.
Also a little tip: capture the mouse on the rectangle so when we move the mouse fast and close to the edges, we don’t loose the mouse resizing/moving with:
Mouse.Capture(sender as UIElement);
in the OnClick delegate and
Mouse.Capture(null);
in the OnLeftButtonUp delegate. Also I used
MouseDevice.SetCursor(desiredCursor);
in SetMouseCursor(object sender, MouseEventArgs e) so I can reuse this in a class.
Best
Hello,
great solution !
Thanks a lot for offering your work.
I´m trying to use your UserControl as Selsction or image processing, to adjust the ROI (Region of Interest) of an picture.
The problem I have is, that i would like to overlay the user control over the Live-view of the camer.
i can´t set the Background to Transparent respectively it will not disapear if I do it.
Do you have any hint for me?
Thanks a lot.
Regards,
Alexander
Sorry but I don’t have any experience with working on live views. I could imagine the controls not working they way you want them to.
However, you could try making a brush out of the live view and then working with a rectangle filled with the brush. See the SaveControlImage method described in this post:
Save WPF control images in C#
I hope that helps.
Hi there. I was actually able to implement exactly what you are asking for the project I am working on. I didn’t have to mess with transparency for the rectangle or image. Rather, in the XAML, I created a canvas that referenced the MouseDown, MouseMove, MouseUp commands and then added an image to that canvas which would be displaying the current frame from the camera. In doing so, the rectangle is always on top of the frame.
I’m a bit of an amateur with C# so I hope that I conveyed my process correctly.
I’m having trouble with this code, I need to leave the transparent canvas, but it lose resize.
How to solve this?
Thanks!
Sorry but I don’t understand your question. If I change the canvas’s Background to Transparent, I can still move and resize it. Is that what you mean?
i am not able to run this code. while running i am getting some thick four sided dictional cursor. i am not able to drag also…
You should get the thick cursor when the mouse is over the rectangle.
Did you download the example or just copy and paste the code? You need to download the example to make sure the event handlers are correctly hooked up to the controls.
i have done copy paste. please send me the link from where i can download the document
Just click the big Download button at the bottom of the post.
I want a similar functionality for textbox I want to move drag and resize textbox but its not working can you please help
It doesn’t work in quite the same way because the TextBox has ideas about what it should do with the mouse events.
You can get the resizing behavior pretty easily by looking for the Preview events. For example, PreviewMouseDown, PreviewMouseMove, and PreviewMouseUp.
Take a look at these posts:
Thank you a lot, im making a game maker in visual c#, this was just the thing i was looking for!
Hi,
This is perfect code for resizing the control with move action, but here use static rectangle with name “rectangle1” that used by you in code statically. But I am looking for something dynamically i.e we can able to add multiple control rectangle or whatever dynamically and able to move and resize it by selection.
Do you have any solution or reference for the same?
See this post:
Move and resize multiple rectangles in WPF and C#
Pingback: Move and resize multiple rectangles in WPF and C# - C# HelperC# Helper
This works superb when the controls are not rotated. Dear sir, please include angle of rotation.. lets say if the rectangle is rotated to 30 by rotate transform.
Unfortunately I think I’ll have to skip this one. At this point you basically need a full-featured drawing program, and I don’t have time to build that (unless someone wants to hire me to do so).
ptTransX= XCosA-YSinA
ptTransY = XSinA+YCosA
A is angle of rotation.
Using this formula should work, i tried to get the vertices of the rectangle when it is rotated by some angle, but while resizing im unable to do so.
OK. So, all your blog posts are created with passion I assume, you spent your own time by writing these posts while nobody asked for, and all of a sudden (when things get a bit complicated) you need to be hired in order to give answers. Interesting.
I don’t think it’s fair to say “when things get a bit complicated.” Many of my posts are extremely complicated. And many of them are things that people asked for. It sounds like you think this should be a free consulting service. If I were super rich, I might be able to do that, but I can’t.
This particular drawing program would take many hundreds of hours. I just don’t have that much free time. In fact, lately I have less and less.
I actually tried to get a similar project rolling with a kickstarter so I would be able to do it, but almost no one signed on.
how can this kind of application works in windows form application on picturbox? instead of wpf application
See these examples to get started:
Draw and move polygons snapping them to a grid in C#
Draw, move, and delete line segments in C#
You should be able to use those techniques to adapt the WPF program to do this. (I may make a Windows Forms example when I have time but I can’t right now.)
Hi, Great work indeed.
a quick question, While moving object “usercontrol” sometimes the mouse looses the object, probably due to high speed of mouse movement. any Idea how to have a workaround for this?
Do you mean you’re using a UserControl instead of a Rectangle? I don’t know why it would do that. I can’t get it to drop the Rectangle.
If you post the XAML code, I’ll try it out.