效果预览:
首先设置DataGridView控件的AllowDrop属性为True,MultiSelect为False,SelectionMode为FullRowSelect
在窗口类里定义基本的变量:
view sourceprint?
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;
|
然后在窗口加载时添加示例数据:
view sourceprint?
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;
|
响应鼠标的按下和抬起事件:
view sourceprint?
01
|
private void dataGridView_MouseDown(object sender, MouseEventArgs e)
|
03
|
// 通过鼠标按下的位置获<script type="text/javascript"><!--mce:0--></script><script type="text/javascript"><!--mce:1--></script><script type="text/javascript"><!--mce:2--></script><script type="text/javascript"><!--mce:3--></script>取所在行的信息
|
04
|
var hitTest = dataGridView.HitTest(e.X, e.Y);
|
05
|
if (hitTest.Type != DataGridViewHitTestType.Cell)
|
08
|
// 记下拖动源数据行的索引及已鼠标按下坐标为中心的不会开始拖动的范围
|
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;
|
鼠标在按下状态移动时开始拖放过程:
view sourceprint?
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)
|
13
|
// 开始拖动,第一个参数表示要拖动的数据,可以自定义,一般是源数据行
|
14
|
var row = dataGridView.Rows[indexOfItemUnderMouseToDrag];
|
15
|
DragDropEffects dropEffect = dataGridView.DoDragDrop(row, DragDropEffects.All);
|
鼠标拖动过程中移动过数据行时执行重绘:
view sourceprint?
01
|
private void dataGridView_DragOver(object sender, DragEventArgs e)
|
04
|
Point p = dataGridView.PointToClient(new Point(e.X, e.Y));
|
07
|
// 如果不是在数据行或者在源数据行上则不能作为拖放的目标
|
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);
|
鼠标拖放至目标行释放时:
view sourceprint?
01
|
private void dataGridView_DragDrop(object sender, DragEventArgs e)
|
04
|
Point p = dataGridView.PointToClient(new Point(e.X, e.Y));
|
07
|
// 或者刚好是源数据行的下一行(本示例中假定拖放操作为拖放至目标行的上方)
|
09
|
var hitTest = dataGridView.HitTest(p.X, p.Y);
|
10
|
if (hitTest.Type != DataGridViewHitTestType.Cell || hitTest.RowIndex == indexOfItemUnderMouseToDrag + 1)
|
13
|
indexOfItemUnderMouseToDrop = hitTest.RowIndex;
|
15
|
// * 执行拖放操作(执行的逻辑按实际需要)
|
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);
|
如果鼠标正拖放至行上方时绘制一条红线:
view sourceprint?
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);
|
用到的方法,强制行进行重绘:
view sourceprint?
01
|
private void OnRowDragOver(int rowIndex)
|
03
|
// 如果和上次导致重绘的行是同一行则无需重绘
|
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