2011-11-18 25 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); 
    } 
}