Drag and Drop Function with Drawing Rectangle C# .net - Forms - c#

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#

Related

Removing a rectangle from imagebox

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.

How to prevent repeating code using events

I am a beginner programmer and I feel like I am repeating code unnecessarily. I want to make a picture puzzle game consisting of 16 pictureboxes. The problem is that I feel like I have to repeat code for each picturebox's events as in the below example:
Point move;
bool isDragging = false;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
move = e.Location;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if(isDragging == true)
{
pictureBox1.Left += e.X - move.X;
pictureBox1.Top += e.Y - move.Y;
pictureBox1.BringToFront();
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
Just create one method for each of your 3 events:
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
move = e.Location;
}
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
if(isDragging == true)
{
// Luckily the sender parameter will tell us which PictureBox we are dealing with
PictureBox pb = (PictureBox)sender;
pb.Left += e.X - move.X;
pb.Top += e.Y - move.Y;
pb.BringToFront();
}
}
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
Then go to each of your 16 picture boxes in the designer and set the MouseUp event handler to point to pictureBox_MouseUp and the MouseMove event handler to point to pictureBox_MouseMove and the MouseDown event handler to point to pictureBox_MouseMove. Do this for each of the 16 picture boxes.
Try to trigger same events for all PictureBox Controls
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
move = e.Location;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
PictureBox pictureBox = sender as PictureBox;
if(isDragging == true)
{
pictureBox .Left += e.X - move.X;
pictureBox .Top += e.Y - move.Y;
pictureBox .BringToFront();
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
Create a new component contained Image component and set dock parent container. Write your drag drop codes into the new component.
For example,
public partial class DraggablePictureBox : UserControl
{
public DraggablePictureBox()
{
InitializeComponent();
}
/// <summary>
/// Sets image of inner picture
/// </summary>
public Image Image
{
get {
return InnerPictureBox.Image;
}
set
{
InnerPictureBox.Image = value;
}
}
private void InnerPictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging == true)
{
this.Left += e.X - move.X;
this.Top += e.Y - move.Y;
this.BringToFront();
}
}
private void InnerPictureBox_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
private void InnerPictureBox_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
move = e.Location;
}
private Point move;
private bool isDragging = false;
}
Now you have a one drag drop code for images.
One way to combat this would be to put these in methods, for example
MovePicturePox(Point move, Point newPos, PictureBox pb)
{
pb.Left += newPos.X - move.X;
pb.Top += newPos.Y - move.Y;
pb.BringToFront();
}
These methods can then be called like so
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if(isDragging == true)
{
MovePictureBox(move, new Point(e.X, y.Y), pictureBox1);
}
}

Graphical error while moving usercontrol (c# win7)

I am having trouble with painting usercontrol on form while moving the control.
The background of the control is shortened if moved to the right or downwards.
My control
public class DotPanel : Control
{
public DotPanel()
{
this.DoubleBuffered = true;
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.FillRectangle(new SolidBrush(Color.Yellow),new Rectangle(this.Location,this.Size));
}
}
The main form just places the usercontrol on specified location and supplies the mouse down/move/up events to do the moving
Basicaly this>>
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
mouseX = e.X;
mouseY = e.Y;
panelX = dp1.Left;
panelY = dp1.Top;
moving = true;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (moving)
{
dp1.Left = panelX + e.X - mouseX;
dp1.Top = panelY + e.Y - mouseY;
this.Invalidate(true);
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
moving = false;
this.Invalidate(true);
}
Thanks in advance for any clues...
the overriden paint was the problem.
exchanging this.Size and this.Location for ClientRectangle.Size and ClientRectangle.Location worked...

Rectangle can't be drawn on the panel by mouse dragging runtime

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);
}

How to draw and move shapes using mouse in C#

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;
}
}

Categories