我想将行从某个位置拖动到同一网格视图中的另一个位置。其他行应根据拖放自动调整。
谢谢
答案 0 :(得分:9)
在应用程序中进行d& d时,我更喜欢使用鼠标事件而不是实际的拖放事件。
1 - 无约束示例
这是一个简单的示例,它使用鼠标事件拖动行,同时在Cell
中放置一个Label
值。
它会在您放置它之后插入行。
dragLabel
部分是可选的..
首先,我们在类级别声明两个辅助变量:
int dragRow = -1;
Label dragLabel = null;
然后我们对CellMouseDown
进行编码以准备Label
..:
private void dataGridView1_CellMouseDown(object sender,DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex<0 || e.RowIndex < 0) return;
dragRow = e.RowIndex;
if (dragLabel == null) dragLabel = new Label();
dragLabel.Text = dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString();
dragLabel.Parent = dataGridView1;
dragLabel.Location = e.Location;
}
在MouseMove
我们只是移动标签。但由于MouseDown
通常会启动细胞选择,我们会清除选择..
private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && dragLabel != null)
{
dragLabel.Location = e.Location;
dataGridView1.ClearSelection();
}
}
真正的工作在MouseUp
。我们需要HitTest
来找出我们所在的行(如果有的话)。我们还需要根据拖动的方向计算目标行。
最后,我们清理Label
..
private void dataGridView1_MouseUp(object sender, MouseEventArgs e)
{
var hit = dataGridView1.HitTest(e.X,e.Y);
int dropRow = -1;
if (hit.Type != DataGridViewHitTestType.None)
{
dropRow = hit.RowIndex;
if (dragRow >= 0 )
{
int tgtRow = dropRow + (dragRow > dropRow ? 1 : 0);
if (tgtRow != dragRow)
{
DataGridViewRow row = dataGridView1.Rows[dragRow];
dataGridView1.Rows.Remove(row);
dataGridView1.Rows.Insert(tgtRow, row);
dataGridView1.ClearSelection();
row.Selected = true;
}
}
}
else { dataGridView1.Rows[dragRow].Selected = true;}
if (dragLabel != null)
{
dragLabel.Dispose();
dragLabel = null;
}
}
一些注意事项:
确保没有新行或修改过的行,或者您无法移动行。我花了一段时间才意识到我必须在最初添加行之前关闭AllowUserToAddRows
..
选择的处理取决于您。如果丢弃失败,我选择拖动行。当我拖入空旷的空间时,我选择让它失败。
<强>更新强>
2 - DataBound示例
如果DGV 数据绑定,则无法直接移动行。相反,您需要移动DataSource
。
我们假设你有DataTable DT
。然后,您可以从中删除行并在任何位置插入行。 (与SQL DBMS表完全不同!)
请注意,DataRow
从DataTable
移除后会丢失其值。因此,我们需要在删除行之前克隆值。除此之外,代码几乎相同。只需用以下内容替换最里面的条件:
if (tgtRow != dragRow)
{
DataRow dtRow = DT.Rows[dragRow];
DataRow newRow = DT.NewRow();
newRow.ItemArray = DT.Rows[dragRow].ItemArray; // we need to clone the values
DT.Rows.Remove(dtRow);
DT.Rows.InsertAt(newRow, tgtRow);
dataGridView1.Refresh();
dataGridView1.Rows[tgtRow].Selected = true;
}