2011-08-30 107 views
1

我想通了如何从how to drag gridview row from one grid to another datagridviews之间拖行,但现在我有一个问题。我可以将该行从gridPODetails拖到DataGridView1。我可以将行拖回到DataGridView1的gridPODetails。但在此之后,我什么也得不到。我希望能够无限地来回拖曳,但我只能往回走。什么可能导致这种情况以及如何纠正?拖放不工作在C#

private void gridPODetails_MouseDown(object sender, MouseEventArgs e) 
     { 
      DataGridView.HitTestInfo info = gridPODetails.HitTest(e.X, e.Y); 

      if (info.RowIndex >= 0) 
      { 
       DataRow view = ((DataTable)(gridPODetails.DataSource)).Rows[info.RowIndex]; 
       if (view != null) 
       { 
        gridPODetails.DoDragDrop(view, DragDropEffects.Copy); 
       } 
      } 
     } 

     private void gridPODetails_DragEnter(object sender, DragEventArgs e) 
     { 
      e.Effect = DragDropEffects.Copy; 
     } 

     private void gridPODetails_DragDrop(object sender, DragEventArgs e) 
     { 
      DataGridView grid = sender as DataGridView; 
      DataTable table = grid.DataSource as DataTable; 
      DataRow row = e.Data.GetData(typeof(DataRow)) as DataRow; 

      if (row != null && table != null && row.Table != table) 
      { 
       table.ImportRow(row); 
       row.Delete(); 
      } 
     } 

     private void dataGridView1_MouseDown(object sender, MouseEventArgs e) 
     { 
      DataGridView.HitTestInfo info = dataGridView1.HitTest(e.X, e.Y); 

      if (info.RowIndex >= 0) 
      { 
       DataRow view = ((DataTable)(dataGridView1.DataSource)).Rows[info.RowIndex]; 
       if (view != null) 
       { 
        dataGridView1.DoDragDrop(view, DragDropEffects.Copy); 
       } 
      } 
     } 

     private void dataGridView1_DragEnter(object sender, DragEventArgs e) 
     { 
      e.Effect = DragDropEffects.Copy; 
     } 

     private void dataGridView1_DragDrop(object sender, DragEventArgs e) 
     { 
      DataGridView grid = sender as DataGridView; 
      DataTable table = grid.DataSource as DataTable; 
      DataRow row = e.Data.GetData(typeof(DataRow)) as DataRow; 

      if (row != null && table != null && row.Table != table) 
      { 
       table.ImportRow(row); 
       row.Delete(); 
      } 
     } 
+2

只是一个猜测,但也许'table.AcceptChanges'可能有帮助的事情 –

+0

@Conrad Frix -where? – MAW74656

+1

'row.Delete()' –

回答

2

row.Delete()后添加table.AcceptChanges()应该让你回来来回移动表之间的行。

这样做的原因可能是因为导入先前已被删除可能导致问题的行。

2

在回答我已经把我是否打算线了多个网格做拖动和拖放我会使用的方法问题下MAW74656的评论。

在本质上我尝试创建一个lambda把所有的单一方法在这里面的功能 - 它可以做,因为它是自己的方法如果需要的话,虽然允许多个来电。

这就是:

Func<DataGridView, IEnumerable<Action>> configureDragDrop = grid => 
{ 
    var dataTable = grid.DataSource as DataTable; 

    /* Event handler definitions here - see below */ 

    grid.MouseDown += mds; 
    grid.DragEnter += des; 
    grid.DragDrop += dds; 

    return new Action[] 
    { 
     () => grid.MouseDown -= mds, 
     () => grid.DragEnter -= des, 
     () => grid.DragDrop -= dds, 
    }; 
}; 

此代码可以让我写这篇文章:

 // form-level field 
     private List<Action> removeHandlers = new List<Action>(); 

     // in the method where `configureDragDrop` is defined 
     removeHandlers.AddRange(configureDragDrop(gridPODetails)); 
     removeHandlers.AddRange(configureDragDrop(dataGridView1)); 
     removeHandlers.AddRange(configureDragDrop(dataGridView2)); 
     removeHandlers.AddRange(configureDragDrop(dataGridView3)); 
     removeHandlers.AddRange(configureDragDrop(dataGridView4)); 
     removeHandlers.AddRange(configureDragDrop(dataGridView5)); 
     removeHandlers.AddRange(configureDragDrop(dataGridView6)); 
     removeHandlers.AddRange(configureDragDrop(dataGridView7)); 
     // etc 

当我关闭了自己的状态,我可以再删除所有的处理器在同一行:

 Array.ForEach(removeHandlers.ToArray(), rh => rh.Invoke()); 

事件处理程序看起来非常类似于原始代码 - 现在只是lambda表单。

MouseDown

  MouseEventHandler mds = (smd, emd) => 
      { 
       var info = grid.HitTest(emd.X, emd.Y); 
       if (info.RowIndex >= 0) 
       { 
        var dr = dataTable.Rows[info.RowIndex]; 
        if (dr != null) 
        { 
         grid.DoDragDrop(dr, DragDropEffects.Copy); 
        } 
       } 
      }; 

DragEnter

  DragEventHandler des = (sde, ede) => 
      { 
       ede.Effect = DragDropEffects.Copy; 
      }; 

DragDrop

  DragEventHandler dds = (sdd, edd) => 
      { 
       var dr = edd.Data.GetData(typeof(DataRow)) as DataRow; 
       if (dr != null) 
       { 
        var dst = dataTable; 
        var src = dr.Table; 
        if (dst != src) 
        { 
         dst.ImportRow(dr); 
         dr.Delete(); 
         src.AcceptChanges(); 
         dst.AcceptChanges(); 
        } 
       } 
      }; 

我希望这有助于。

+0

+1非常好的通用的解决方案 –

+0

@Enigmativity - 我渴望在这里重用代码,但我“新来lambda表达式,有什么好的介绍文章 – MAW74656

+0

@ MAW74656 - ?要开始学习lambda表达式只是把它们当作”内联方法“写作'功能 GetLength = t => t.Length;'和调用代码时的'private int GetLength(string t){return t.Length;}'一样''int len = GetLength(”Hello“ );从那里开始,并且任何代理('Func','Action','EventHandler <>'等等)都可以使用lambda语法,否则搜索StackOverflow,因为这里有大量的例子。 – Enigmativity