DGV拖放-行消失

本文关键字:消失 -行 拖放 DGV | 更新日期: 2023-09-27 18:15:02

我试图编写一些代码,以允许我的应用程序的用户在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上插入不工作

DGV拖放-行消失

下面是代码的清理版本:

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

问题在grdCons_DragDrop()。因为您提到DGV绑定到一个数据表,调用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);
    }
}