效果预览:
首先设置DataGridView控件的AllowDrop属性为True,MultiSelect为False,SelectionMode为FullRowSelect
在窗口类里定义基本的变量:
02 | DataTable dataTable = new DataTable(); |
04 | private int indexOfItemUnderMouseToDrag = -1; |
06 | private int indexOfItemUnderMouseToDrop = -1; |
08 | private int indexOfItemUnderMouseOver = -1; |
10 | private Rectangle dragBoxFromMouseDown = Rectangle.Empty; |
然后在窗口加载时添加示例数据:
01 | private void MainForm_Load( object sender, EventArgs e) |
03 | dataTable.Columns.Add( "ID" , typeof ( int )); |
04 | dataTable.Columns.Add( "Column1" , typeof ( string )); |
05 | dataTable.Columns.Add( "Column2" , typeof ( string )); |
06 | for ( int id = 1; id <= 20; id++) |
07 | dataTable.Rows.Add(id, string .Format( "A{0}" , id), string .Format( "B{0}" , id)); |
09 | dataGridView.DataSource = dataTable; |
响应鼠标的按下和抬起事件:
01 | private void dataGridView_MouseDown( object sender, MouseEventArgs e) |
04 | var hitTest = dataGridView.HitTest(e.X, e.Y); |
05 | if (hitTest.Type != DataGridViewHitTestType.Cell) |
09 | indexOfItemUnderMouseToDrag = hitTest.RowIndex; |
10 | if (indexOfItemUnderMouseToDrag > -1) |
12 | Size dragSize = SystemInformation.DragSize; |
13 | dragBoxFromMouseDown = new Rectangle( new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize); |
16 | dragBoxFromMouseDown = Rectangle.Empty; |
20 | private void dataGridView_MouseUp( object sender, MouseEventArgs e) |
23 | dragBoxFromMouseDown = Rectangle.Empty; |
鼠标在按下状态移动时开始拖放过程:
01 | private void dataGridView_MouseMove( object sender, MouseEventArgs e) |
04 | if ((e.Button & MouseButtons.Left) != MouseButtons.Left) |
07 | if (dragBoxFromMouseDown == Rectangle.Empty || dragBoxFromMouseDown.Contains(e.X, e.Y)) |
10 | if (indexOfItemUnderMouseToDrag < 0) |
14 | var row = dataGridView.Rows[indexOfItemUnderMouseToDrag]; |
15 | DragDropEffects dropEffect = dataGridView.DoDragDrop(row, DragDropEffects.All); |
鼠标拖动过程中移动过数据行时执行重绘:
01 | private void dataGridView_DragOver( object sender, DragEventArgs e) |
04 | Point p = dataGridView.PointToClient( new Point(e.X, e.Y)); |
08 | var hitTest = dataGridView.HitTest(p.X, p.Y); |
09 | if (hitTest.Type != DataGridViewHitTestType.Cell || hitTest.RowIndex == indexOfItemUnderMouseToDrag) |
11 | e.Effect = DragDropEffects.None; |
17 | e.Effect = DragDropEffects.Move; |
19 | OnRowDragOver(hitTest.RowIndex); |
鼠标拖放至目标行释放时:
01 | private void dataGridView_DragDrop( object sender, DragEventArgs e) |
04 | Point p = dataGridView.PointToClient( new Point(e.X, e.Y)); |
09 | var hitTest = dataGridView.HitTest(p.X, p.Y); |
10 | if (hitTest.Type != DataGridViewHitTestType.Cell || hitTest.RowIndex == indexOfItemUnderMouseToDrag + 1) |
13 | indexOfItemUnderMouseToDrop = hitTest.RowIndex; |
17 | var tempRow = dataTable.NewRow(); |
18 | tempRow .ItemArray = dataTable.Rows[indexOfItemUnderMouseToDrag].ItemArray; |
19 | dataTable.Rows.RemoveAt(indexOfItemUnderMouseToDrag); |
21 | if (indexOfItemUnderMouseToDrag < indexOfItemUnderMouseToDrop) |
22 | indexOfItemUnderMouseToDrop--; |
24 | dataTable.Rows.InsertAt(tempRow, indexOfItemUnderMouseToDrop); |
如果鼠标正拖放至行上方时绘制一条红线:
1 | private void dataGridView_RowPostPaint( object sender, DataGridViewRowPostPaintEventArgs e) |
4 | if (e.RowIndex == indexOfItemUnderMouseOver) |
5 | e.Graphics.FillRectangle(Brushes.Red, e.RowBounds.X, e.RowBounds.Y, e.RowBounds.Width, 2); |
用到的方法,强制行进行重绘:
01 | private void OnRowDragOver( int rowIndex) |
04 | if (indexOfItemUnderMouseOver == rowIndex) |
07 | int old = indexOfItemUnderMouseOver; |
08 | indexOfItemUnderMouseOver = rowIndex; |
12 | dataGridView.InvalidateRow(old); |
16 | dataGridView.InvalidateRow(rowIndex); |
这样就是可以实现拖放效果了,拖放后的逻辑操作你可以自定义
[点这里下载完整的示例代码]
原文地址:http://www.cnblogs.com/jeffrey84/archive/2010/01/14/1647265.html