2011-11-18 53 views
4

我正在尝试编写一些代码,以允许我的应用程序的用户在DataGridView中拖放行以重新排序它们。问题是,被拖动的行在被删除时会消失 - 所以拖放操作只会删除该行。这里是我的代码:DGV DragDrop - 行消失

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

你有没有得到过这个解决方案?即使在尝试第一次回答代码后,我也遇到了同样的问题。 – David

回答

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

非常感谢 - 我仍然有同样的问题。这可能是由于DGV的约束方式吗?它目前绑定到一个DataTable – Chris

+0

我与这个用户的代码有同样的问题。除了DataTable之外,我们都在同一条船上,没有将数据备份到我们的DataSources。我认为这是主要的罪魁祸首,但是,应该有一种方法可以在不需要将数据存储在某种其他容器中的情况下工作,然后从中填充DataTable。 – David

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