C# Drag & Drop labels - c#

i have a problem with drag&drop. I have code:
void labelWorker_MouseEvent(object sender, MouseEventArgs e)
{
Label labelWorker = (Label)sender;
labelWorker.DoDragDrop(labelWorker, DragDropEffects.Move);
labelWorker.MouseDown += new MouseEventHandler(labelWorker_MouseDown);
labelWorker.MouseMove += new MouseEventHandler(labelWorker_MouseMove);
labelWorker.MouseUp += new MouseEventHandler(labelWorker_MouseUp);
}
bool isDragged = false;
Point ptOffset;
void labelWorker_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Label labelWorker = (Label)sender;
isDragged = true;
Point ptStartPosition = labelWorker.PointToScreen(new Point(e.X, e.Y));
ptOffset = new Point();
ptOffset.X = labelWorker.Location.X - ptStartPosition.X;
ptOffset.Y = labelWorker.Location.Y - ptStartPosition.Y;
}
else
{
isDragged = false;
}
}
void labelWorker_MouseMove(object sender, MouseEventArgs e)
{
Label labelWorker = (Label)sender;
if (isDragged)
{
Point newPoint = labelWorker.PointToScreen(new Point(e.X, e.Y));
newPoint.Offset(ptOffset);
labelWorker.Location = newPoint;
}
}
void labelWorker_MouseUp(object sender, MouseEventArgs e)
{
Label labelWorker = (Label)sender;
isDragged = false;
}
Label starts freaking out when I try to move it. I think the problem is in
void labelWorker_MouseMove(object sender, MouseEventArgs e)
{
Label labelWorker = (Label)sender;
if (isDragged)
{
Point newPoint = labelWorker.PointToScreen(new Point(e.X, e.Y));
newPoint.Offset(ptOffset);
labelWorker.Location = newPoint;
}
}

Ok. I just made it :)
bool clicked = false;
int iOldX;
int iOldY;
int iClickX;
int iClickY;
void labelWorker_MouseDown(object sender, MouseEventArgs e)
{
Label labelWorker = (Label)sender;
if (e.Button == MouseButtons.Left)
{
Point p = ConvertFromChildToForm(e.X, e.Y, labelWorker);
iOldX = p.X;
iOldY = p.Y;
iClickX = e.X;
iClickY = e.Y;
clicked = true;
}
}
void labelWorker_MouseMove(object sender, MouseEventArgs e)
{
Label labelWorker = (Label)sender;
if (clicked)
{
Point p = new Point(); // New Coordinate
p.X = e.X + labelWorker.Left;
p.Y = e.Y + labelWorker.Top;
labelWorker.Left = p.X - iClickX;
labelWorker.Top = p.Y - iClickY;
}
}
void labelWorker_MouseUp(object sender, MouseEventArgs e)
{
clicked = false;
}
private Point ConvertFromChildToForm(int x, int y, Control control)
{
Point p = new Point(x, y);
control.Location = p;
return p;
}

Related

How to store locations properly

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

Resize Line by mouse

I'm drawing a line on a Form and when it finished will be draw a rectangle on line. I need to resize the line after clicking on the rectangle. Any way to do that?
This before:
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawLine(Pens.Red, start.X, start.Y, end.X, end.Y);
if (isMouse == false )
{
rect1.X = start.X - 5;
rect1.Y = start.Y - 5;
rect1.Width = 10;
rect1.Height = 10;
rect2.X = end.X - 5;
rect2.Y = end.Y - 5;
rect2.Width = 10;
rect2.Height = 10;
e.Graphics.DrawRectangle(Pens.Blue, rect1.X, rect1.Y,rect1.Width, rect1.Height);
e.Graphics.DrawRectangle(Pens.Blue, rect2.X, rect2.Y, rect2.Width, rect2.Height);
}
base.OnPaint(e);
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (start.X == 0 && start.Y == 0)
{
isMouse = true;
start = e.Location;
}
else {
resize = true;
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (isMouse == true) {
end = e.Location;
}
if (rect1.Contains(e.Location)&&resize ) {
start = e.Location;
}
else if (rect2.Contains(e.Location)&&resize) {
end = e.Location;
}
Refresh();
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (isMouse == true)
{
end = e.Location;
isMouse = false;
}
}
This will be after:

Why are my graphics not appearing on the panel c#

The code displayed below is used for drawing different shapes, the problem that i am facing is that when i use the same code to display the drawings on the windows form it displays,,,but when i try to display them on a panel..it shows as blank during runtime..please have a look at the code and tell me where i am going wrong. Thank in advance to whoever replies to this post!
private ArrayList ds;
private Point mold;
private Point mcurr;
private int mshape;
private float mwidth;
private Color mcolor;
public Form1()
{
InitializeComponent();
ds = new ArrayList();
mshape = 0;
//mwidth = 1;
//mcolor = Color.Black;
DoubleBuffered = true;
}
private void Form1_Load(object sender, EventArgs e)
{
richTextBox1.SelectionFont = new Font("Arial", 9);
richTextBox1.SelectionBullet = true;
richTextBox1.SelectionColor = Color.Red;
}
private Rectangle rec(Point p1, Point p2)
{
Rectangle a = new Rectangle();
a.X = (p1.X > p2.X ? p2.X : p1.X);
a.Y = (p1.Y > p2.Y ? p2.Y : p1.Y);
a.Width = Math.Abs(p1.X - p2.X);
a.Height = Math.Abs(p1.Y - p2.Y);
return a;
}
private void draw(Graphics e, Point mold, Point mcur, int mshape, float mwidth, Color mcolor)
{
Pen p = new Pen(mcolor, mwidth);
switch (mshape)
{
case 0:
e.DrawRectangle(p, rec(mold, mcur));
break;
case 1:
e.DrawEllipse(p, rec(mold, mcur));
break;
case 2:
e.DrawLine(p, mold, mcur);
break;
case 3:
//this.Invalidate();
break;
}
}
private void toolStripButtonRectangle_Click(object sender, EventArgs e)
{
mshape = 0;
}
private void toolStripButtonEllipse_Click(object sender, EventArgs e)
{
mshape = 1;
}
private void toolStripButtonLine_Click(object sender, EventArgs e)
{
mshape = 2;
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
panel1.Cursor = Cursors.Cross;
if (e.Button == MouseButtons.Left)
{
this.mold = e.Location;
}
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
panel1.Cursor = Cursors.Default;
Class1 a = new Class1(mold, mcur, mshape, mwidth, mcolor);/// create a class
ds.Add(a);
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mcur = e.Location;
Invalidate();
}
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
foreach (Class1 a in ds)
{
draw(e.Graphics, a.old, a.cur, a.shape, a.width, a.color);
}
draw(e.Graphics, mold, mcur, mshape, mwidth, mcolor);
}
private void btn_Clear_Click(object sender, EventArgs e)
{
Graphics erase = panel1.CreateGraphics();
erase.Clear(panel1.BackColor);
// g1.Clear(Color.Transparent);
}
}
}

C# drag and drop picturebox

I have 7 pictureboxes and I want to drag and drop each one of them. I have made the drag and drop but it takes with it the original picturebox which I drag it doesn't leave it on its place. This is my code:
this.pbAND.MouseDown += pictureBox_MouseDown;
pbAND.MouseMove += pictureBox_MouseMove;
pbAND.MouseUp += pictureBox_MouseUp;
this.pbOR.MouseDown += pictureBox_MouseDown;
pbOR.MouseMove += pictureBox_MouseMove;
pbOR.MouseUp += pictureBox_MouseUp;
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
p = (PictureBox)sender;
downPoint = e.Location;
var dragImage = (Bitmap)p.Image;
IntPtr icon = dragImage.GetHicon();
Cursor.Current = new Cursor(icon);
p.Parent = this;
p.BringToFront();
DestroyIcon(icon);
}
}
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
p = (PictureBox)sender;
if (e.Button == MouseButtons.Left)
{
p.Left += e.X - downPoint.X;
p.Top += e.Y - downPoint.Y;
}
}
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
p = (PictureBox)sender;
Control c = GetChildAtPoint(new Point(p.Left - 1, p.Top));
if (c == null) c = this;
Point newLoc = c.PointToClient(p.Parent.PointToScreen(p.Location));
p.Parent = c;
p.Location = newLoc;
}
but it takes with it the original picturebox which I drag it doesn't
leave it on its place.
So you want to make a copy when the PictureBox is dropped?
In the MouseDown() handler, store the original location in the Tag() property:
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
p = (PictureBox)sender;
p.Tag = p.Location; // <-- store the Location in the Tag() property
// ... rest of the existing code ...
}
}
In the MouseUp() handler, put a New PictureBox in the current location and reset the original:
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
p = (PictureBox)sender;
// create a new PictureBox that looks like the original:
PictureBox PB = new PictureBox();
PB.Size = p.Size;
PB.Image = p.Image;
PB.SizeMode = p.SizeMode;
PB.BorderStyle = p.BorderStyle;
// etc...make it look the same
// ...and place it:
Control c = GetChildAtPoint(new Point(p.Left - 1, p.Top));
if (c == null) c = this;
Point newLoc = c.PointToClient(p.Parent.PointToScreen(p.Location));
PB.Parent = c;
PB.Location = newLoc;
p.Parent.Controls.Add(PB); // <-- add new PB to the form!
// put the original back where it started:
p.Location = (Point)p.Tag;
}

DGV DragDrop - row disappearing

I'm attempting to write some code to allow the users of my application to drag and drop rows in a DataGridView to reorder them. The problem is, the row that is being dragged disappears when it's dropped - so dragging and dropping has the effect of just removing that row. Here is my code:
private Rectangle dragBoxFromMouseDown;
private int rowIndexFromMouseDown;
private int rowIndexOfItemUnderMouseToDrop;
private void grdCons_MouseMove(object sender, MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
if (dragBoxFromMouseDown != Rectangle.Empty && !dragBoxFromMouseDown.Contains(e.X, e.Y))
{
DragDropEffects dropEffect = grdCons.DoDragDrop(grdCons.Rows[rowIndexFromMouseDown], DragDropEffects.Move);
}
}
}
private void grdCons_MouseDown(object sender, MouseEventArgs e)
{
rowIndexFromMouseDown = grdCons.HitTest(e.X, e.Y).RowIndex;
if (rowIndexFromMouseDown != -1)
{
Size dragSize = SystemInformation.DragSize;
dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize);
}
else
{
dragBoxFromMouseDown = Rectangle.Empty;
}
}
private void grdCons_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void grdCons_DragDrop(object sender, DragEventArgs e)
{
Point clientPoint = grdCons.PointToClient(new Point(e.X, e.Y));
rowIndexOfItemUnderMouseToDrop = grdCons.HitTest(clientPoint.X, clientPoint.Y).RowIndex;
if (e.Effect == DragDropEffects.Move)
{
DataGridViewRow rowToMove = e.Data.GetData(typeof(DataGridViewRow)) as DataGridViewRow;
grdCons.Rows.RemoveAt(rowIndexFromMouseDown);
grdCons.Rows.Insert(rowIndexOfItemUnderMouseToDrop, rowToMove);
}
}
At a guess, the Insert on the DGV on the DragDrop event isn't working.
Here is a cleaned up version of your code that works:
public Form1()
{
InitializeComponent();
grdCons.Rows.Add(7);
for (int i = 0; i < grdCons.Rows.Count; i++)
{
grdCons.Rows[i].Cells[0].Value = i;
grdCons.Rows[i].Cells[1].Value = "Cell " + i;
}
grdCons.AllowDrop = true;
grdCons.AllowUserToAddRows = false;
grdCons.AllowUserToDeleteRows = false;
grdCons.MouseMove += new MouseEventHandler(grdCons_MouseMove);
grdCons.MouseDown += new MouseEventHandler(grdCons_MouseDown);
grdCons.DragOver += new DragEventHandler(grdCons_DragOver);
grdCons.DragDrop += new DragEventHandler(grdCons_DragDrop);
}
private int rowIndexFromMouseDown;
private void grdCons_MouseMove(object sender, MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
grdCons.DoDragDrop(grdCons.Rows[rowIndexFromMouseDown], DragDropEffects.Move);
}
}
private void grdCons_MouseDown(object sender, MouseEventArgs e)
{
rowIndexFromMouseDown = grdCons.HitTest(e.X, e.Y).RowIndex;
}
private void grdCons_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void grdCons_DragDrop(object sender, DragEventArgs e)
{
Point clientPoint = grdCons.PointToClient(new Point(e.X, e.Y));
int targetIndex = grdCons.HitTest(clientPoint.X, clientPoint.Y).RowIndex;
if (e.Effect == DragDropEffects.Move)
{
DataGridViewRow rowToMove = e.Data.GetData(typeof(DataGridViewRow)) as DataGridViewRow;
grdCons.Rows.RemoveAt(rowIndexFromMouseDown);
grdCons.Rows.Insert(targetIndex, rowToMove);
}
}
The problem lies in grdCons_DragDrop(). Because you mentioned the DGV is bound to a DataTable calling grdCons.Rows.Insert(targetIndex, rowToMove) will trigger an InvalidOperationException. When a DGV is data-bound you need to manipulate the DataSource rather than the DGV. Here's the correct way to call grdCons_DragDrop().
private void grdCons_DragDrop(object sender, DragEventArgs e)
{
DataTable tbl = (DataTable)grdCons.DataSource;
Point clientPoint = grdCons.PointToClient(new Point(e.X, e.Y));
int targetIndex = grdCons.HitTest(clientPoint.X, clientPoint.Y).RowIndex;
if (e.Effect == DragDropEffects.Move)
{
DataRow row = tbl.NewRow();
row.ItemArray = tbl.Rows[rowIndexFromMouseDown].ItemArray; //copy the elements
tbl.Rows.RemoveAt(rowIndexFromMouseDown);
tbl.Rows.Insert(targetIndex, rowToMove);
}
}

Categories

Resources