c# 中dataGridView  如何实现行行的拖动,即行之间相互交换位置
如题 在c# 中dataGridView  如何实现行行的拖动,即行之间相互交换位置
------解决方案--------------------        private void dataGridView_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
       {
           if ((e.Clicks < 2) && (e.Button==MouseButtons.Left))
           {
               if ((e.ColumnIndex ==-1) && (e.RowIndex > -1))
                   dataGridView.DoDragDrop(dataGridView.Rows[e.RowIndex], DragDropEffects.Move);
           }
       }
鼠标在单元格里移动时激活拖放功能,我这里判断了如果是只有单击才执行拖放,双击我要执行其他功能,而且只有点在每行的表头那一格拖动才行,否则会影响编辑其他单元格的值。如果希望点在任何一个单元格都可以拖动,去掉判断列序号的条件就行了。
       private void dataGridView_DragDrop(object sender, DragEventArgs e)
       {
           int idx = GetRowFromPoint(e.X, e.Y);
           if (idx < 0) return;
           if (e.Data.GetDataPresent(typeof(DataGridViewRow)))
           {
               DataGridViewRow row = (DataGridViewRow)e.Data.GetData(typeof(DataGridViewRow));
		dataGridView.Rows.Remove(row);		
		dataGridView.Rows.Insert(idx,row);
		selectionIdx=idx;
           }
       }
拖动到目的地后的操作,GetRowFromPoint是根据鼠标按键被释放时的鼠标位置计算行序号。
       private int GetRowFromPoint(int x, int y)
       {
           for (int i = 0; i < dataGridView.RowCount; i++)
           {
               Rectangle rec = dataGridView.GetRowDisplayRectangle(i, false);
               if (dataGridView.RectangleToScreen(rec).Contains(x, y))
                   return i;
           }
           return -1;
       }
到这里基本功能其实已经完成。只是有些细节需要调整。一般我们希望拖动完成后被选中的行是刚才拖动的那一行,但是DataGridView会自动选中顶替我们拖动的那一行位置的新行,也就是说,比如我们拖动第3行到其他位置,结束后,被选中的行仍然是新的第3行。在DragDrop方法里设置也没有用,DataGridView选中新行的行为是在DragDrop结束后。所以我们必须自己记录选中行的行号。在类中添加一个字段selectionIdx。
       private void dataGridView_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
       {
           if (e.RowIndex>=0)
               selectionIdx = e.RowIndex;
	}
注意DragDrop方法最后,selectionIdx被赋值为拖动行的新行号。
       private void dataGridView_SelectionChanged(object sender, EventArgs e)
       {
           if ((dataGridView.Rows.Count > 0) && (dataGridView.SelectedRows.Count>0) && (dataGridView.SelectedRows[0].Index != selectionIdx))
           {
               if (dataGridView.Rows.Count <= selectionIdx)
                   selectionIdx = dataGridView.Rows.Count - 1;
               dataGridView.Rows[selectionIdx].Selected = true;
               dataGridView.CurrentCell = dataGridView.Rows[selectionIdx].Cells[0];
           }
       }
在这里判断,如果selectionIdx的值和当前选中的行号不同,则选中行号为selectionIdx的这一行。
       private void dataGridView_DragEnter(object sender, DragEventArgs e)
       {
           e.Effect = DragDropEffects.Move;
       }
这个方法设置在DataGridView里拖动时,鼠标不会显示禁止拖放的光标。