I'm new to programming in C# and wanted to ask for a little bit of help. I'm currently trying to move a color-filled rectangle that I draw on a Windows Application form with my left mouse button, and I'm trying to drag-and-drop it to another location using my right mouse button. Currently I've managed to draw the rectangle, but the right click is dragging the entire form along.
Here's my code:
public partial class Form1 : Form
{
private Point MouseDownLocation;
public Form1()
{
InitializeComponent();
this.DoubleBuffered = true;
}
Rectangle rec = new Rectangle(0, 0, 0, 0);
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.DeepSkyBlue, rec);
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
rec = new Rectangle(e.X, e.Y, 0, 0);
Invalidate();
}
if (e.Button == MouseButtons.Right)
{
MouseDownLocation = e.Location;
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
rec.Width = e.X - rec.X;
rec.Height = e.Y - rec.Y;
Invalidate();
}
if (e.Button == MouseButtons.Right)
{
this.Left = e.X + this.Left - MouseDownLocation.X;
this.Top = e.Y + this.Top - MouseDownLocation.Y;
}
}
}
I only need to drag-and-drop the rectangles with right mouse button.
EDIT: Thanks to you all i got my answer very fast and here's the code that works:
public partial class Form1 : Form
{
private Point MouseDownLocation;
public Form1()
{
InitializeComponent();
this.DoubleBuffered = true;
}
Rectangle rec = new Rectangle(0, 0, 0, 0);
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.DeepSkyBlue, rec);
//Generates the shape
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
//can also use this one:
//if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
rec = new Rectangle(e.X, e.Y, 0, 0);
Invalidate();
}
if (e.Button == MouseButtons.Right)
{
MouseDownLocation = e.Location;
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
rec.Width = e.X - rec.X;
rec.Height = e.Y - rec.Y;
this.Invalidate();
}
if (e.Button == MouseButtons.Right)
{
rec.Location = new Point((e.X - MouseDownLocation.X) + rec.Left, (e.Y - MouseDownLocation.Y) + rec.Top);
MouseDownLocation = e.Location;
this.Invalidate();
}
}
}
This seems to work
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
rec.Width = e.X - rec.X;
rec.Height = e.Y - rec.Y;
this.Invalidate();
}
if (e.Button == MouseButtons.Right)
{
rec.Location = new Point((e.X-MouseDownLocation.X) + rec.Left, (e.Y-MouseDownLocation.Y) + rec.Top);
MouseDownLocation = e.Location;
this.Invalidate();
}
}
try this one :
Notice that I add timer to the form in this method you don't need to call
Invalidate on mouse event the timertick is calling to the Refresh() so the form
will paint himself in each tick..
public partial class Form1 : Form
{
private Point MouseDownLocation;
public Form1()
{
InitializeComponent();
this.DoubleBuffered = true;
timer1.Start(); // add timer to the form
}
Rectangle rec = new Rectangle(0, 0, 0, 0);
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.DeepSkyBlue, rec);
}
private void timer1_Tick(object sender, EventArgs e)
{
Refresh();
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
rec.Width = e.X - rec.X;
rec.Height = e.Y - rec.Y;
}
else if (e.Button == MouseButtons.Right)
{
rec.X = e.X - MouseDownLocation.X;
rec.Y = e.Y - MouseDownLocation.Y;
}
}
protected override void OnMouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
MouseDownLocation = e.Location;
}
}
Related
i tried this code but when i drag and move label inside panel is normal but when i drag to edge bound of panel it disappear i want it to stop on panel bound is there a way for that?
private void lbl29_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
MouseDownLocation = e.Location;
}
panel1.Invalidate();
}
private void lbl29_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
lbl29.Left = e.X + lbl29.Left - MouseDownLocation.X;
lbl29.Top = e.Y + lbl29.Top - MouseDownLocation.Y;
}
}
You can try these:
Controls.SetChildIndex(lbl29, 0); or
Controls.SetChildIndex(panel1, 1); or
lbl29.BringToFront(); or
panel1.SendToBack();
But Controls.SetChildIndex(lbl29, 0); and Controls.SetChildIndex(panel1, 1); are more useful.
I borrowed some code to draw a rectangle on an image, e.g. like a selection box. Right now, the code draws a rectangle any time you click and drag your mouse. If you simply left-click without dragging, nothing at all happens - the existing rectangle stays put. If you click and drag a new rectangle, the old rectangle disappears.
That's almost exactly like I want (I'm not wanting to permanently draw on the image... yet...), but with one change: I'd like for a single left-click to make the rectangle disappear as well.
The code is as follows:
public partial class ScreenSelection : Form
{
private Point RectStartPoint;
private Rectangle Rect = new Rectangle();
private Brush selectionBrush = new SolidBrush(Color.FromArgb(128, 72, 145, 220));
public ScreenSelection(DataTable buttonData)
{
InitializeComponent();
}
private void Canvas_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
RectStartPoint = e.Location;
Invalidate();
}
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left)
return;
Point tempEndPoint = e.Location;
Rect.Location = new Point(
Math.Min(RectStartPoint.X, tempEndPoint.X),
Math.Min(RectStartPoint.Y, tempEndPoint.Y));
Rect.Size = new Size(
Math.Abs(RectStartPoint.X - tempEndPoint.X),
Math.Abs(RectStartPoint.Y - tempEndPoint.Y));
Canvas.Invalidate();
}
private void Canvas_Paint(object sender, PaintEventArgs e)
{
// Draw the rectangle...
if (Canvas.Image != null)
{
if (Rect != null && Rect.Width > 0 && Rect.Height > 0)
{
e.Graphics.FillRectangle(selectionBrush, Rect);
}
}
}
}
I also have the user load a bitmap in as the image of the canvas, so once the user does that, canvas.image won't equal null.
so how can I make that rectangle disappear on a left click? I'm already doing an invalidate on the left-click, and that's clearly not getting rid of it.
I tried forcing the rectangle size on a left-click by doing:
if (e.Button == MouseButtons.Left)
{
RectStartPoint = e.Location;
Rect.Height = 0;
Rect.Width = 0;
Invalidate();
}
and tried Rect.Size, Rect = Rectangle.Empty, Canvas.Refresh()...
How can I accomplish this?
Edit:
I've also tried saving the graphics state and restoring it. That doesn't work... (no errors, just not getting rid of the rectangle)
Finally found a way to do it where I keep the drawing inside the paint event to improve performance / remove flicker...
It all had to do with fillRectangles
here's the working code:
public partial class ScreenSelection : Form
{
private Point RectStartPoint;
private Rectangle Rect = new Rectangle();
private Brush selectionBrush = new SolidBrush(Color.FromArgb(128, 72, 145, 220));
private List<Rectangle> Rects = new List<Rectangle>();
private bool RectStart = false;
public ScreenSelection(DataTable buttonData)
{
InitializeComponent();
}
private void Canvas_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (RectStartPoint == e.Location)
{
int i = Rects.Count;
if (i > 0) { Rects.RemoveAt(i - 1); }
Canvas.Refresh();
}
}
}
private void Canvas_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
RectStartPoint = e.Location;
int i = Rects.Count;
if (i >= 1) { Rects.RemoveAt(i - 1); }
RectStart = false;
Canvas.Refresh();
}
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left)
return;
Point tempEndPoint = e.Location;
Rect.Location = new Point(
Math.Min(RectStartPoint.X, tempEndPoint.X),
Math.Min(RectStartPoint.Y, tempEndPoint.Y));
Rect.Size = new Size(
Math.Abs(RectStartPoint.X - tempEndPoint.X),
Math.Abs(RectStartPoint.Y - tempEndPoint.Y));
if (!RectStart)
{
Rects.Add(Rect);
RectStart = true;
}
else
{
Rects[(Rects.Count - 1)] = Rect;
}
Canvas.Invalidate();
}
private void Canvas_Paint(object sender, PaintEventArgs e)
{
// Draw the rectangle...
if (Canvas.Image != null)
{
if (Rects.Count > 0)
{
e.Graphics.FillRectangles(selectionBrush, Rects.ToArray());
}
}
}
}
The bonus to this is that if I'm careful, I'll be able to also make some rectangles permanent while removing others.
I have a PictureBox1 draggable with this code:
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
x = e.X;
y = e.Y;
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (pictureBox1.Left + pictureBox1.Width> panel1.Width)
pictureBox1.Left += (e.X - x);
}
}
But I can't get bound restrictions,
I just want move the Picture inside a Panel, like this:
Example
Any ideas?
Thanks
Try this:
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
int left = 0;
if (pictureBox1.Left >= 0 && pictureBox1.Right <= panel1.Width)
left = pictureBox1.Left + (e.X - x);
left = Math.Min(panel1.Width - pictureBox1.Width , left);
left = Math.Max(0, left);
pictureBox1.Left = left;
}
}
I am trying to draw a rectangle on a panel, but nothing is drawn. Below is the code to show how I draw a rectangle on the panel. In my code SetSelectionRect() is used to set the rectangle to be drawn. For these I use following methods.
private void Panel_MouseDown(object sender, MouseEventArgs e)
{
Point point = new Point();
this.mouseDown = true;
this.Panel.SendToBack();
point = this.Panel.PointToClient(Cursor.Position);
point.X = e.X;
point.Y = e.Y;
this.selectionStart.X = point.X;
this.selectionStart.Y = point.Y;
}
private void Panel_MouseMove(object sender, MouseEventArgs e)
{
if (!this.mouseDown)
{
return;
}
else
{
this.mouseMove = true;
Point point = this.Panel.PointToClient(Cursor.Position);
point.X = e.X;
point.Y = e.Y;
this.selectionEnd.X = point.X;
this.selectionEnd.Y = point.Y;
this.SetSelectionRect();
////this.Panel.Invalidate();
////this.Invalidate();
}
}
private void Panel_MouseUp(object sender, MouseEventArgs e)
{
SetSelectionRect();
this.GetSelectedControls();
this.mouseDown = false;
this.mouseMove = false;
////this.Panel.Invalidate();
////this.Invalidate();
this.Panel.Refresh();
}
private void Panel_Paint(object sender, PaintEventArgs e)
{
////base.OnPaint(e); drawRect = true when RectangleToolStripMenuItem is Clicked.
if (this.drawRect)
{
using (Pen pen = new Pen(Color.Black, 1F))
{
this.rectangle = new RectangleShape();
this.Panel.SendToBack();
this.shapeContainer1.Shapes.Add(this.rectangle);
this.rectangle.Location = this.selection.Location;
this.rectangle.Size = this.selection.Size;
this.rectangle.Name = "rectShape";
this.shapeContainer1.Size = this.Panel.Size;
this.shapeContainer1.Location = this.Panel.Location;
this.rectangle.Enabled = false;
this.rectangle.MouseClick += new MouseEventHandler(this.mouseclick);
this.rectangle.MouseMove += new MouseEventHandler(this.mouseMove);
this.rectangle.MouseDown += new MouseEventHandler(this.mouseDown);
this.rectangle.MouseUp += new MouseEventHandler(this.mouseUp);
this.drawRect = false;
}
}
}
protected override void OnPaint (PaintEventArgs e)
{
base.OnPaint(e);
}
What's wrong with the code?
The problem is base.OnPaint(e); is raising an Paint event, where you placed base.OnPaint(e);, so it calling itself again and again.
private void panel_Paint(object sender, PaintEventArgs e)
{
//base.OnPaint(e); // remove it from here
// something to do.
}
base.OnPaint(e); should be called in overriden method:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
}
I want to drag and drop that I have drawn on the forms. Here is my code for drawing the rectangle. An this works fine.
Rectangle rec = new Rectangle(0, 0, 0, 0);
public Form1()
{
InitializeComponent();
this.DoubleBuffered = true;
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.Aquamarine, rec);
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
rec = new Rectangle(e.X, e.Y, 0, 0);
Invalidate();
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
rec.Width = e.X - rec.X;
rec.Height = e.Y - rec.Y;
Invalidate();
}
}
Now I want to drag and drop that rectangle in to a different place.
Pls help How to do that
Thank You
yohan
I have written a helper class for this kind of stuff:
class ControlMover
{
public enum Direction
{
Any,
Horizontal,
Vertical
}
public static void Init(Control control)
{
Init(control, Direction.Any);
}
public static void Init(Control control, Direction direction)
{
Init(control, control, direction);
}
public static void Init(Control control, Control container, Direction direction)
{
bool Dragging = false;
Point DragStart = Point.Empty;
control.MouseDown += delegate(object sender, MouseEventArgs e)
{
Dragging = true;
DragStart = new Point(e.X, e.Y);
control.Capture = true;
};
control.MouseUp += delegate(object sender, MouseEventArgs e)
{
Dragging = false;
control.Capture = false;
};
control.MouseMove += delegate(object sender, MouseEventArgs e)
{
if (Dragging)
{
if (direction != Direction.Vertical)
container.Left = Math.Max(0, e.X + container.Left - DragStart.X);
if (direction != Direction.Horizontal)
container.Top = Math.Max(0, e.Y + container.Top - DragStart.Y);
}
};
}
}
Then I just Initialize it in my form load event with my control:
ControlMover.Init(myControl, myContainer, ControlMover.Direction.Any);
Well, you don't have a control to move. It's a rectangle. But hopefully, you'll get the idea.
UPDATE: Have you checked out the related questions listed in this page? Try:
Drag and drop rectangle in C#