I have this form that allows the user to create pictureboxes by clicking and dragging them around with mouse movement. How can I store the coordinates (locations) of where the pictureboxes are each time one is added or when one is moved to a new spot? I am trying to store them in a list as strings for exportation.
private void Form_MouseClick(object sender, MouseEventArgs e)
{
// create new control
PictureBox pictureBox = new PictureBox();
pictureBox.Location = new Point(e.X, e.Y);
pictureBox.BackColor = Color.Red;
this.Controls.Add(pictureBox);
// bind event for each PictureBox
pictureBox.MouseDown += pictureBox_MouseDown;
pictureBox.MouseUp += pictureBox_MouseUp;
pictureBox.MouseMove += pictureBox_MouseMove;
}
Point mouseDownPoint = Point.Empty;
Rectangle rect = Rectangle.Empty;
bool isDrag = false;
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mouseDownPoint = e.Location;
rect = (sender as PictureBox).Bounds;
}
}
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (isDrag)
{
isDrag = false;
(sender as PictureBox).Location = rect.Location;
this.Refresh();
}
reset();
}
}
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDrag = true;
rect.Location = this.PointToClient((sender as PictureBox).PointToScreen(new Point(e.Location.X - mouseDownPoint.X, e.Location.Y - mouseDownPoint.Y)));
this.Refresh();
}
}
private void reset()
{
mouseDownPoint = Point.Empty;
rect = Rectangle.Empty;
isDrag = false;
}
To save the loaction of each picturebox, you can define a dictionary to save the key-value pair.
First, define the dictionary box_location_Pairs as a global variable.
Then add the new item to dictionary when "click to a create new picturebox".
Dictionary<PictureBox, Point> box_location_Pairs = new Dictionary<PictureBox, Point>();
// ...
private void Form_MouseClick(object sender, MouseEventArgs e)
{
PictureBox pictureBox = new PictureBox();
pictureBox.Location = new Point(e.X, e.Y);
box_location_Pairs.Add(pictureBox, pictureBox.Location);
// ...
}
If the picturebox is moved, modify its value.
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (isDrag)
{
isDrag = false;
(sender as PictureBox).Location = rect.Location;
box_location_Pairs[sender as PictureBox] = rect.Location; // modifty key-value pair
this.Refresh();
}
reset();
}
}
Related
I am trying to create a Form in Visual Studio Windows Forms Apps C# in which during runtime the user or operator can create a new picturebox with a left mouse click and then have the ability to move each picturebox created.
I really do not know where to begin. Anyone have any ideas?
To add a new PictureBox dynamically, you can subscribe to the event Form_MouseClick and create the PictureBox like this:
public Form1()
{
InitializeComponent();
this.MouseClick += Form_MouseClick;
}
private void Form_MouseClick(object sender, MouseEventArgs e)
{
PictureBox pictureBox = new PictureBox();
// cursor location
pictureBox.Location = new Point(e.X, e.Y);
pictureBox.BackColor = Color.Red;
this.Controls.Add(pictureBox);
}
To drag and move the PictureBox, you also nee to subscribe to the event MouseDown, MouseUp, and MouseMove.
Here is a simple demo you can refer to.
private void Form_MouseClick(object sender, MouseEventArgs e)
{
// create new control
PictureBox pictureBox = new PictureBox();
pictureBox.Location = new Point(e.X, e.Y);
pictureBox.BackColor = Color.Red;
this.Controls.Add(pictureBox);
// bind event for each PictureBox
pictureBox.MouseDown += pictureBox_MouseDown;
pictureBox.MouseUp += pictureBox_MouseUp;
pictureBox.MouseMove += pictureBox_MouseMove;
}
Point mouseDownPoint = Point.Empty;
Rectangle rect = Rectangle.Empty;
bool isDrag = false;
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mouseDownPoint = e.Location;
rect = (sender as PictureBox).Bounds;
}
}
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (isDrag)
{
isDrag = false;
(sender as PictureBox).Location = rect.Location;
this.Refresh();
}
reset();
}
}
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDrag = true;
rect.Location = this.PointToClient((sender as PictureBox).PointToScreen(new Point(e.Location.X - mouseDownPoint.X, e.Location.Y - mouseDownPoint.Y)));
this.Refresh();
}
}
private void reset()
{
mouseDownPoint = Point.Empty;
rect = Rectangle.Empty;
isDrag = false;
}
You can add the form elements during runtime:
var picture = new PictureBox
{
Name = "pictureBox",
Size = new Size(16, 16),
Location = new Point(100, 100),
Image = Image.FromFile("test.jpg"),
};
this.Controls.Add(picture);
Afterward, you can move it with the Mouse Events
private void Brick_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
}
private void Brick_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
Brick1.Left = e.X;
Brick1.Top = e.Y;
}
}
public void Brick_MouseUp(object sender, MouseEventArgs m)
{
isDragging = false;
}
It kinda works but it glitches out when you move it (The picturebox teleports around the screen rapidly). https://www.youtube.com/watch?v=hWazyAnGNBE
You need to use the PointToClient method of the Form
var relativePoint = this.PointToClient(new Point(X, Y));
// Or
var relativePoint = this.PointToClient(Cursor.Position);
Control.PointToClient Method (Point)
Computes the location of the specified screen point into client
coordinates.
Update
private void Brick_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
var relativePoint = this.PointToClient(Cursor.Position);
Brick1.Left = relativePoint.X;
Brick1.Top = relativePoint.Y;
}
}
I want to know how i can move a image that i create with System.DrawImage() with mouse. I try with this but dont work:
private void Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
Point mousePt = new Point(e.X, e.Y);
if (rectA.Contains(mousePt))
{
isImageClicked = false;
}
}
private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
Point mousePt = new Point(e.X, e.Y);
if (rectA.Contains(mousePt))
{
isImageClicked = true;
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
Point mousePt = new Point(e.X, e.Y);
if (rectA.Contains(mousePt) && isImageClicked)
{
rectA.X = mousePt.X;
rectA.Y = mousePt.Y;
this.Invalidate();
}
}
I think that have some way to refresh that, but i dont know!
Hi I'm using the code below to draw a circle on a pictureBox, The problem is I don't know why some times if I draw a circle it whon show until I draw an other, some times it will show on the first circle.
public partial class Form1 : Form
{
private bool isMoving = false;
private Point mouseDownPosition = Point.Empty;
private Point mouseMovePosition = Point.Empty;
private List<Tuple<Point, Point>> lines = new List<Tuple<Point, Point>>();
public Form1()
{
InitializeComponent();
//
// pictureBox1
//
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(231, 235);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
this.pictureBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseDown);
this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseMove);
this.pictureBox1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseUp);
this.Controls.Add(this.pictureBox1);
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
var g = e.Graphics;
if (isMoving)
{
g.Clear(pictureBox1.BackColor);
g.DrawLine(Pens.Black, mouseDownPosition, mouseMovePosition);
foreach (var line in lines)
{
g.DrawLine(Pens.Black, line.Item1, line.Item2);
}
}
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
isMoving = true;
mouseDownPosition = e.Location;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (isMoving)
{
mouseMovePosition = e.Location;
pictureBox1.Invalidate();
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (isMoving)
{
lines.Add(Tuple.Create(mouseDownPosition, mouseMovePosition));
}
isMoving = false;
}
}
Use Refresh() instead of using Invalidate(). This will force the re-paint event to be called. Note that you may see a performance drop if you excessively repaint the screen.
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (isMoving)
{
mouseMovePosition = e.Location;
pictureBox1.Refresh();
}
}
I don't see any circles in your sample:)
I noticed your code was behaving a bit weird, when I added the following it seemed to make it run a bit better.
this.pictureBox1.MouseClick += pictureBox1_MouseClick;
...
void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
isMoving = false;
}
Hope this helps :)
I have this code for dragging on a Panel but its not doing the thing.
I have to choose if I will just Drag&drop or Resize.
I think theres something wrong with my code here in form load.
Anyway I have 5 labels here and a panel named as label1, label2, label3, label4, label5 on panel1.
private void form_Load(object sender, EventArgs e)
{
//for drag and drop
//this.panel1.AllowDrop = true; // or Allow drop in the panel.
foreach (Control c in this.panel1.Controls)
{
c.MouseDown += new MouseEventHandler(c_MouseDown);
}
this.panel1.DragOver += new DragEventHandler(panel1_DragOver);
this.panel1.DragDrop += new DragEventHandler(panel1_DragDrop);
//end of drag and drop
}
void c_MouseDown(object sender, MouseEventArgs e)
{
Control c = sender as Control;
c.DoDragDrop(c, DragDropEffects.Move);
}
void panel1_DragDrop(object sender, DragEventArgs e)
{
Control c = e.Data.GetData(e.Data.GetFormats()[0]) as Control;
lblResizeAmtWord.Visible = false;
if (c != null)
{
c.Location = this.panel1.PointToClient(new Point(e.X, e.Y));
//this.panel1.Controls.Add(c); //disable if already on the panel
}
}
void panel1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
I used the MouseDown, Up and Move Event of the Control I want to move. Let's say my control name is ctrlToMove.
private Point _Offset = Point.Empty;
private void ctrlToMove_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_Offset = new Point(e.X, e.Y);
}
}
private void ctrlToMove_MouseUp(object sender, MouseEventArgs e)
{
_Offset = Point.Empty;
}
private void ctrlToMove_MouseMove(object sender, MouseEventArgs e)
{
if (_Offset != Point.Empty)
{
Point newlocation = ctrlToMove.Location;
newlocation.X += e.X - _Offset.X;
newlocation.Y += e.Y - _Offset.Y;
ctrlToMove.Location = newlocation;
}
}