DGV DragDrop - 行消失

时间:2011-11-18 15:01:48

标签: c# datagridview drag-and-drop

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

2 个答案:

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