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:
Related
I am currently working on a topdown game made in windows forms. In the game, your character rotates after your mouse and you can shoot a shot from your character in the direction of your mouse. To create multiple areas in the game, I chose to use groupboxes as separate areas in the game that you can switch between using buttons but I've run in to a problem. I can no longer rotate or move my character or even shoot within the groupboxes.
I've tried setting breakpoints and discovered that the keyup, keydown and mousemove methods are not being called but I don't know why. For some reason I get an error when i release space in the btnSave_Click method which i marked in the code.
static Image originalImage;
bool pRight, pLeft, pUp, pDown;
string[] Saves;
Save[] RSaves = new Save[4];
Save yoursave;
Save temp;
int slot;
NewGame newgame;
SavedGames savedgames;
string savedata, name = "";
int lvl = 1;
double exp = 0, money = 0;
int pSpeed = 5;
double deltaY, deltaX;
float interval = 7;
Point start;
Point nextStart;
Point cursor;
float radian;
const double Rad2Grad = (180 / Math.PI);
public MainGame()
{
InitializeComponent();
pbPlayer.BringToFront();
gbxTown.AllowDrop = true;
gbxQ1.AllowDrop = true;
pbShot.Location = pbPlayer.Location;
// newgame = new NewGame();
// savedgames = new SavedGames();
originalImage = pbPlayer.Image;
}
public void setSaves(string savedata, int slot)
{
Saves = savedata.Split('#');
string a1 = Saves[0];
string a2 = Saves[1];
string a3 = Saves[2];
string a4 = Saves[3];
RSaves[0] = temp.StringToSaves(temp, a1);
RSaves[1] = temp.StringToSaves(temp, a2);
RSaves[2] = temp.StringToSaves(temp, a3);
RSaves[3] = temp.StringToSaves(temp, a4);
yoursave = RSaves[slot - 1];
name = yoursave.getName();
this.slot = slot;
Controls.Add(pbPlayer);
Controls.Add(pbShot);
}
private void MainGame_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.A)
{
pRight = false;
pLeft = true;
}
else if (e.KeyData == Keys.D)
{
pRight = true;
pLeft = false;
}
else if (e.KeyData == Keys.S)
{
pUp = true;
pDown = false;
}
else if (e.KeyData == Keys.W)
{
pUp = false;
pDown = true;
}
if (e.KeyData == Keys.Space)
{
start = pbPlayer.Location;
cursor = Cursor.Position;
nextStart = start;
deltaY = cursor.Y - start.Y;
deltaX = cursor.X - start.X;
double test = Angle(start, cursor);
radian = (float)(Angle(start, cursor) - 175);
timer2.Enabled = true;
}
}
private void MainGame_KeyUp_1(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.A)
{
pLeft = false;
}
else if (e.KeyData == Keys.D)
{
pRight = false;
}
else if (e.KeyData == Keys.S)
{
pUp = false;
}
else if (e.KeyData == Keys.W)
{
pDown = false;
}
if (e.KeyData == Keys.Space)
{
timer2.Stop();
pbShot.Location = start;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
MovePlayer();
//checkCollision();
}
private void btnNextArea_Click(object sender, EventArgs e)
{
pbPlayer.Parent = gbxQ1;
pbShot.Parent = gbxQ1;
gbxQ1.Location = new Point(0, 0);
gbxTown.Location = new Point(605, 0);
pbPlayer.Location = new Point(100, 200);
pbShot.Location = pbPlayer.Location;
}
private void btnSave_Click(object sender, EventArgs e)
{
newgame = new NewGame();
savedgames = new SavedGames();
RSaves[slot - 1] = new Save(name, money, lvl, exp);
for (int i = 0; i < 4; i++) //When the Spacebar is released, a System.IndexOutOfRangeException error happens for i.
{
Saves[i] = RSaves[i].SavesToString();
}
savedata = Saves[0] + Saves[1] + Saves[2] + Saves[3];
System.IO.File.WriteAllLines(#"saves.txt", Saves);
newgame.setSaves(savedata);
savedgames.setSaves(savedata);
}
private void btnBack_Click(object sender, EventArgs e)
{
pbPlayer.Parent = gbxTown;
pbShot.Parent = gbxTown;
gbxTown.Location = new Point(0, 0);
gbxQ1.Location = new Point(605, 0);
pbPlayer.Location = new Point(100, 200);
pbShot.Location = pbPlayer.Location;
}
private void MainGame_MouseMove_1(object sender, MouseEventArgs e)
{
var y2 = e.Y;
var y1 = (this.pbPlayer.Location.Y + (this.pbPlayer.Height / 2));
var x2 = e.X;
var x1 = (this.pbPlayer.Location.X + (this.pbPlayer.Width / 2));
var angle = (float)Math.Atan2((y1 - y2), (x1 - x2));
pbPlayer.Image = RotateImage(originalImage, (angle * 57));
}
private double Angle(Point start, Point end)
{
return (float)Math.Atan2(end.Y - start.Y, end.X - start.X) * 57;
}
private void timer2_Tick_1(object sender, EventArgs e)
{
nextStart.X -= Convert.ToInt16(interval * ((float)Math.Cos(radian / Rad2Grad)));
nextStart.Y -= Convert.ToInt16(interval * ((float)Math.Sin(radian / Rad2Grad)));
pbShot.Location = nextStart;
}
public static Image RotateImage(Image img, float rotationAngle)
{
Bitmap bmp = new Bitmap(img.Width, img.Height);
Graphics gfx = Graphics.FromImage(bmp);
gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);
gfx.RotateTransform(rotationAngle);
gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
gfx.DrawImage(img, new Point(0, 0));
gfx.Dispose();
return bmp;
}
private void MovePlayer()
{
if (pRight == true && pbPlayer.Left < 900)
{
pbPlayer.Left += pSpeed;
}
else if (pLeft == true && pbPlayer.Left > 0)
{
pbPlayer.Left -= pSpeed;
}
else if (pUp == true && pbPlayer.Top < 600)
{
pbPlayer.Top += pSpeed;
}
else if (pDown == true && pbPlayer.Top > 0)
{
pbPlayer.Top -= pSpeed;
}
}
The expected outcome is for the movement, aiming and firing to work as intended within the groupboxes but currently they do not execute in the code while in the groupboxes. It works fine in the form but not in the groupboxes. I would appriciate any help.
How to receive a path of relocation of a mouse between the 1st clicking and the 2nd?
private void OnMouseDown(object sender, MouseEventArgs e)
{
Log(string.Format("MouseDown \t\t {0}\n", e.Button));
LogMousePosition(string.Format("\n\nx={0:0000}\ny={1:0000}", e.X, e.Y));
if (lastX != -100 && lastY != -100)
{
shortestDistanse = Convert.ToInt64(Math.Sqrt((Math.Pow(e.X - lastX, 2)) + (Math.Pow(e.Y - lastY, 2))));
LogMousePosition(string.Format("\nshortDistanse\t\t {0}\n", shortestDistanse));
}
lastX = e.X;
lastY = e.Y;
}
If you just want the distance between the two points use pythagora.
Example:
private double GetDistance(Point p1, Point p2) {
int x = Math.Abs(p1.X - p2.X);
int y = Math.Abs(p1.Y - p2.Y);
return Math.Sqrt( Math.Pow(x, 2) + Math.Pow(y, 2));
}
You may try something like
// form fields
bool pressed;
List<Point> path;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (!pressed)
{
pressed = true;
path = new List<Point>();
path.Add(e.Location);
}
else
{
pressed = false;
// calculate distance from List
// log distance
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (pressed)
{
path.Add(e.Location);
}
}
However, the MouseMove event will be triggered only above the form. If the mouse is outside of it - distance is not taken into account. It also doesn't work when moving over other controls, but we can add to them MouseMove handlers too.
I could make
string pathMList = "C:\\logs/testMList.txt";`
private void HookManager_MouseMove(object sender, MouseEventArgs e)
{
labelMousePosition.Text = string.Format("x={0:0000}; y={1:0000}", e.X, e.Y);
if (mouseDownMove == 2)
{
LogMList(string.Format("\nx={0:0000} y={1:0000}", e.X, e.Y));
}
}
private void OnMouseDown(object sender, MouseEventArgs e)
{
Log(string.Format("MouseDown \t\t {0}\n", e.Button));
LogMousePosition(string.Format("\n\nx={0:0000}\ny={1:0000}", e.X, e.Y));
if (lastX != -100 && lastY != -100)
{
shortestDistanse = Convert.ToInt64(Math.Sqrt((Math.Pow(e.X - lastX, 2)) + (Math.Pow(e.Y - lastY, 2))));
LogMousePosition(string.Format("\nshortDistanse\t\t {0}\n", shortestDistanse));
LogMList(string.Format("\n\n NEW CLICK\n\nx={0:0000} y={1:0000}", e.X, e.Y));
}
lastX = e.X;
lastY = e.Y;
mouseDownMove = 2;
}
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;
}
What i want is that if i drawed a rectangle on one of the items in the pictureBox next time i click the button it will display those items when i click on them in the listBox only the rectangles i drawed.
This is what i tried so far:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using DannyGeneral;
using System.Diagnostics;
namespace MinimizeCapture
{
public partial class Form1 : Form
{
Point p1 = new Point(0, 0);
Rectangle recttest;
private Rectangle Rect;
private Rectangle[] rectangles;
private Rectangle RectClone;
private bool btn = false;
private Point RectStartPoint = Point.Empty;
private Point RectEndPoint = Point.Empty;
private Brush selectionBrush = new SolidBrush(Color.Red);
private Pen pen;
private string selectedIndex;
private List<string> drawnItems = new List<string>();
private bool ClearGraphics;
public Form1()
{
InitializeComponent();
var windows = OpenWindowGetter.FindWindowsWithText();
ClearGraphics = false;
this.DoubleBuffered = true;
btn = false;
pen = new Pen(selectionBrush);
buttonSnap.Enabled = false;
backgroundWorker1.RunWorkerAsync();
}
private void buttonSnap_Click(object sender, EventArgs e)
{
ClearGraphics = true;
this.listBoxSnap.Items.Clear();
this.pictureBoxSnap.Image = null;
backgroundWorker1.RunWorkerAsync();
}
private void CutRectangle()
{
for (int i = 0; i < rectangles.Length; i++)
{
if (!rectangles[i].IsEmpty)
{
}
}
}
private void listBoxSnap_SelectedIndexChanged(object sender, EventArgs e)
{
WindowSnap snap = this.listBoxSnap.SelectedItem as WindowSnap;
selectedIndex = this.listBoxSnap.SelectedIndex.ToString();
this.pictureBoxSnap.Image = snap.Image;
for (int i = 0; i < rectangles.Length; i++)
{
if (rectangles[i] != RectClone)
{
ClearGraphics = false;
}
else
{
ClearGraphics = true;
}
}
}
private void checkBoxForceMDI_CheckedChanged(object sender, EventArgs e)
{
WindowSnap.ForceMDICapturing = (sender as CheckBox).Checked;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.Add("Minimized Windows"); }));
listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true,true).ToArray()); }));
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
rectangles = new Rectangle[listBoxSnap.Items.Count];
buttonSnap.Enabled = true;
}
private void pictureBoxSnap_Paint(object sender, PaintEventArgs e)
{
if (pictureBoxSnap.Image != null)
{
{
if (ClearGraphics == false)
{
if (rectangles[listBoxSnap.SelectedIndex] != Rectangle.Empty)
{
e.Graphics.DrawRectangle(Pens.Firebrick, rectangles[listBoxSnap.SelectedIndex]);
}
if (recttest.Width > 10 && recttest.Height > 10)
e.Graphics.DrawRectangle(Pens.Firebrick, recttest);
}
}
}
}
private void pictureBoxSnap_MouseMove(object sender, MouseEventArgs e)
{
if (btn == true)
{
ClearGraphics = false;
RectEndPoint = e.Location;
int currentindex = listBoxSnap.SelectedIndex;
rectangles[currentindex] = RectClone;
Rect = getRect(RectStartPoint, RectEndPoint);
RectClone = Rect;
pictureBoxSnap.Invalidate();
}
}
private void pictureBoxSnap_MouseDown(object sender, MouseEventArgs e)
{
RectStartPoint = e.Location;
btn = true;
Rect = Rectangle.Empty;
RectClone = Rectangle.Empty;
p1 = e.Location;
}
private void pictureBoxSnap_MouseUp(object sender, MouseEventArgs e)
{
recttest = rectangles[listBoxSnap.SelectedIndex];
ClearGraphics = false;
btn = false;
RectEndPoint = e.Location;
pictureBoxSnap.Invalidate();
int currentindex = listBoxSnap.SelectedIndex;
rectangles[currentindex] = RectClone;
if (e.Location.X > p1.X)
{
recttest.X = p1.X;
recttest.Width = e.Location.X - p1.X;
}
else
{
recttest.X = e.Location.X;
recttest.Width = p1.X - e.Location.X;
}
//Top and Height
if (e.Location.Y > p1.Y)
{
recttest.Y = p1.Y;
recttest.Height = e.Location.Y - p1.Y;
}
else
{
recttest.Y = e.Location.Y;
recttest.Height = p1.Y - e.Location.Y;
}
if (recttest.Width > 10 && recttest.Height > 10)
pictureBoxSnap.Invalidate();
}
Rectangle getRect(Point p1, Point p2)
{
Point p = new Point(Math.Min(p1.X, p2.X), Math.Min(p1.Y, p2.Y));
Size s = new Size(Math.Abs(p1.X - p2.X), Math.Abs(p1.Y - p2.Y));
return new Rectangle(p, s);
}
private void ConfirmRectangle_Click(object sender, EventArgs e)
{
ConfirmRectangle.ForeColor = Color.Red;
ConfirmRectangle.Enabled = false;
StreamWriter w = new StreamWriter(#"c:\temp\Settings.txt", true);
w.WriteLine("Rectangle Location: " + RectClone.Location + " Rectangle Size: " + RectClone.Size + " Selected Index: " + selectedIndex);
textBoxIndex.Text = selectedIndex.ToString();
w.Close();
pictureBoxSnap.Image = CropImage();
}
private Bitmap CropImage()
{
Bitmap pic = pictureBoxSnap.Image as Bitmap;
Bitmap cropped = new Bitmap(recttest.Width, recttest.Height);
using (Graphics g = Graphics.FromImage(cropped))
{
g.DrawImage(pic, new Rectangle(0, 0, recttest.Width, recttest.Height),
recttest, GraphicsUnit.Pixel);
}
return cropped;
}
}
}
For the test i called the rectangle variable recttest.
In the mouse up event i'm getting the rectangle i drawed in the current selected item in the listBox.
I can't upload here images but what i get is when i click the ConfirmRectangle button i see the the rectangle i drawed in the pictureBox the same as it was and the image in the pictureBox get resize get very very big from the inside like it was zoom in.
Instead what i wanted to get is the part of the image in the pictureBox that was marked/drawed by the rectangle. Like the rectangle is the border so when i click on the ConfirmRectangle i will see the part of the image was in the pictureBox in the rectangle and only this all the rest should not be shown.
I should see rectangle with inside the part of the image. Not to resize or zoom in the image only to cut the part was marked/drawn on by the rectangle.
try following method.
Boolean bHaveMouse;
Point ptOriginal = new Point();
Point ptLast = new Point();
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
bHaveMouse = true;
// Store the "starting point" for this rubber-band rectangle.
ptOriginal.X = e.X;
ptOriginal.Y = e.Y;
// Special value lets us know that no previous
// rectangle needs to be erased.
ptLast.X = -1;
ptLast.Y = -1;
}
// Convert and normalize the points and draw the reversible frame.
private void MyDrawReversibleRectangle(Point p1, Point p2)
{
Rectangle rc = new Rectangle();
// Convert the points to screen coordinates.
p1 = pictureBox.PointToScreen(p1);
p2 = pictureBox.PointToScreen(p2);
// Normalize the rectangle.
if (p1.X < p2.X)
{
rc.X = p1.X;
rc.Width = p2.X - p1.X;
}
else
{
rc.X = p2.X;
rc.Width = p1.X - p2.X;
}
if (p1.Y < p2.Y)
{
rc.Y = p1.Y;
rc.Height = p2.Y - p1.Y;
}
else
{
rc.Y = p2.Y;
rc.Height = p1.Y - p2.Y;
}
// Draw the reversible frame.
rect = new Rectangle(pictureBox.PointToClient(rc.Location), rc.Size);
ControlPaint.DrawReversibleFrame(rc, Color.Gray, FrameStyle.Dashed);
}
Rectangle rect = Rectangle.Empty;
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
// Set internal flag to know we no longer "have the mouse".
bHaveMouse = false;
// If we have drawn previously, draw again in that spot
// to remove the lines.
if (ptLast.X != -1)
{
Point ptCurrent = new Point(e.X, e.Y);
MyDrawReversibleRectangle(ptOriginal, ptLast);
}
// Set flags to know that there is no "previous" line to reverse.
ptLast.X = -1;
ptLast.Y = -1;
ptOriginal.X = -1;
ptOriginal.Y = -1;
pictureBox.Invalidate();
}
private void pictureBox_Paint(object sender, PaintEventArgs e)
{
if (rect.Width > 10 && rect.Height > 10)
{
e.Graphics.DrawRectangle(Pens.Gray, rect);
pictureBox1.Image = CropImage();
}
}
private Bitmap CropImage()
{
Bitmap pic = pictureBox.Image as Bitmap;
Bitmap cropped = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(cropped))
{
g.DrawImage(pic, new Rectangle(0, 0, rect.Width, rect.Height),
rect, GraphicsUnit.Pixel);
}
return cropped;
}
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
Point ptCurrent = new Point(e.X, e.Y);
// If we "have the mouse", then we draw our lines.
if (bHaveMouse)
{
// If we have drawn previously, draw again in
// that spot to remove the lines.
if (ptLast.X != -1)
{
MyDrawReversibleRectangle(ptOriginal, ptLast);
}
// Update last point.
ptLast = ptCurrent;
// Draw new lines.
MyDrawReversibleRectangle(ptOriginal, ptCurrent);
}
}
Output
I am using ControPaint.DrawReversibleFrame method to draw rubber band. To read more about this method u can refere this tutorial
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);
}
}