我正在尝试编写一些代码,以允许我的应用程序的用户在DataGridView中拖放行来重新排序它们。问题是,被拖动的行在被删除时会消失 - 因此拖放会产生删除该行的效果。这是我的代码:
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);
}
}
猜测,DragDrop事件上的DGV上的插入不起作用。
答案 0 :(得分:0)
以下是适用的代码的清理版本:
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);
}
}
答案 1 :(得分:0)
问题在于grdCons_DragDrop()
。因为您提到DGV绑定到DataTable,调用grdCons.Rows.Insert(targetIndex, rowToMove)
将触发InvalidOperationException
。当DGV受数据限制时,您需要操纵DataSource
而不是DGV。这是调用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);
}
}