dataGridView 如何實現行行的拖動,即行之間相互交換位置
阿新 • • 發佈:2019-02-11
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裡拖動時,滑鼠不會顯示禁止拖放的游標。
{
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裡拖動時,滑鼠不會顯示禁止拖放的游標。