C# 拖放DataGridView中的行

C# 拖放DataGridView中的行,c#,.net,vb.net,datagridview,drag-and-drop,C#,.net,Vb.net,Datagridview,Drag And Drop,我有带DataGridView的windows窗体,需要在此DataGridView中启用拖放行 它是从数据库中填充的。我的代码无法正常工作,因为在第一次拖放之后,我无法将行拖放到正确的位置 这是从数据库中填充DataGridView的Load表单 DataTable bsPeople; Rectangle dragBoxFromMouseDown; int rowIndexFromMouseDown; int rowIndexOfItemUnderMouseToDrop;

我有带DataGridView的windows窗体,需要在此DataGridView中启用拖放行

它是从数据库中填充的。我的代码无法正常工作,因为在第一次拖放之后,我无法将行拖放到正确的位置

这是从数据库中填充
DataGridView
Load
表单

DataTable bsPeople;
Rectangle dragBoxFromMouseDown;
    int rowIndexFromMouseDown;
    int rowIndexOfItemUnderMouseToDrop; 
    private void Form1_Load(object sender, EventArgs e)
    {
        DataGridView1.AllowDrop = true;
        bsPeople= objPeople.ReturnPeople(); // fill data from SQL Server 
        DataGridView1.DataSource = bsPeople;
    }
这是拖放事件

private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
    {
        if (((e.Button ==MouseButtons.Left)))
        {
            if (((dragBoxFromMouseDown != Rectangle.Empty)
                        && !dragBoxFromMouseDown.Contains(e.X, e.Y)))
            {
                DragDropEffects dropEffect = DataGridView1.DoDragDrop(DataGridView1.Rows[rowIndexFromMouseDown], DragDropEffects.Move);
            }
        }
    }

    private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
    {
        rowIndexFromMouseDown = DataGridView1.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 dataGridView1_DragOver(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.Move;
    }

    private void dataGridView1_DragDrop(object sender, DragEventArgs e)
    {
        Point clientPoint = DataGridView1.PointToClient(new Point(e.X, e.Y));
        rowIndexOfItemUnderMouseToDrop = DataGridView1.HitTest(clientPoint.X, clientPoint.Y).RowIndex;
        if ((e.Effect == DragDropEffects.Move))
        {
            DataGridViewRow rowToMove = (DataGridViewRow)e.Data.GetData(typeof(DataGridViewRow));
            object[] celldata=new object[DataGridView1.ColumnCount];
            for (int col = 0; (col
                        <= (rowToMove.Cells.Count - 1)); col++)
            {
                celldata[col] = rowToMove.Cells[col].Value;
            }

            DataRow row = bsPeople.NewRow();
            row.ItemArray = celldata;
            bsPeople.Rows.InsertAt(row, rowIndexOfItemUnderMouseToDrop);
            rowToMove.DataGridView.Rows.Remove(rowToMove);

        }
    }
}
private void dataGridView1\u MouseMove(对象发送方,MouseEventArgs e)
{
如果(((e.Button==MouseButtons.Left)))
{
if(((dragBoxFromMouseDown!=矩形.空)
&&!dragBoxFromMouseDown.Contains(e.X,e.Y)))
{
DragDropEffects dropEffect=DataGridView1.DoDragDrop(DataGridView1.Rows[RowIndexFromousedown],DragDropEffects.Move);
}
}
}
私有void datagridview 1_MouseDown(对象发送方,MouseEventArgs e)
{
rowIndexFromMouseDown=DataGridView1.HitTest(e.X,e.Y).RowIndex;
如果((rowIndexFromMouseDown!=-1))
{
大小dragSize=SystemInformation.dragSize;
dragBoxFromMouseDown=新矩形(新点(e.X-(dragSize.Width/2),e.Y-(dragSize.Height/2)),dragSize);
}
其他的
{
dragBoxFromMouseDown=矩形。为空;
}
}
私有无效dataGridView1_DragOver(对象发送方,DragEventArgs e)
{
e、 效果=DragDropEffects.Move;
}
私有void dataGridView1_DragDrop(对象发送方,DragEventArgs e)
{
Point clientPoint=DataGridView1.PointToClient(新点(e.X,e.Y));
rowIndexOfItemUnderMouseToDrop=DataGridView1.HitTest(clientPoint.X,clientPoint.Y).RowIndex;
如果((e.Effect==DragDropEffects.Move))
{
DataGridViewRowToMove=(DataGridViewRow)e.Data.GetData(typeof(DataGridViewRow));
object[]celldata=新对象[DataGridView1.ColumnCount];
for(int col=0;(col

拖放

您需要删除并插入右侧的数据行。请尝试以下操作:

private void DGV_DragDropData(object sender, DragEventArgs e)
{
   Point clientPoint = DGV.PointToClient(new Point(e.X, e.Y));
   rowIndexOfItemUnderMouseToDrop =
       DGV.HitTest(clientPoint.X, clientPoint.Y).RowIndex;
   if (e.Effect == DragDropEffects.Move)
   {
      DataGridViewRow rowToMove = (DataGridViewRow)e.Data.GetData(typeof(DataGridViewRow));
      // find the row to move in the datasource:
      DataRow oldrow = ((DataRowView)rowToMove.DataBoundItem).Row;
      // clone it:
      DataRow newrow = bsPeople.NewRow();
      newrow.ItemArray = oldrow.ItemArray;
      bsPeople.Rows.InsertAt(newrow, rowIndexOfItemUnderMouseToDrop);
      bsPeople.Rows.Remove(oldrow);
   }
}
请注意,代码只移动一行。要移动多行,还需要一些技巧

行的状态:

还请注意,您可能需要根据需要设置新行的
RowState
。添加新行时,您可能希望通过调用
newRow.AcceptChanges()
将其设置为
不变的状态,或者根据原始行的状态设置为其他状态

要修改
行状态
,请应用以下规则:

  • DataRow
    必须驻留在
    DataTable
    中;在您刚刚创建它之后,状态是
    未附加的
    ,您无法更改它
  • 只有
    Unchanged
    行可以通过
    SetAdded
    SetModified
    方法进行更改;因此必须先调用
    AcceptChanges()
这应该可以做到:

   if (oldrow.RowState != DataRowState.Unchanged) newrow.AcceptChanges();
   if (oldrow.RowState == DataRowState.Added) newrow.SetAdded();
   if (oldrow.RowState == DataRowState.Modified) newrow.SetModified();

这些行必须在新行添加到表后添加。
我有一个MSDN代码示例,用于通过按钮上下移动行,这不是您想要的,但基本逻辑可用于vb.net和C#的几种语言扩展方法。无需下载,只需浏览代码即可。我没有包括在此处取消编码,因为它使用按钮而不是拖放。