效果预览:
首先设置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