拖放Datagrid的行查看Winform C#

时间:2017-05-10 10:57:21

标签: c# datagridview

我想将行从某个位置拖动到同一网格视图中的另一个位置。其他行应根据拖放自动调整。

谢谢

1 个答案:

答案 0 :(得分:9)

在应用程序中进行d& d时,我更喜欢使用鼠标事件而不是实际的拖放事件。

1 - 无约束示例

这是一个简单的示例,它使用鼠标事件拖动行,同时在Cell中放置一个Label值。

它会在您放置它之后插入行。

dragLabel部分是可选的..

enter image description here

首先,我们在类级别声明两个辅助变量:

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表完全不同!)

请注意,DataRowDataTable移除后会丢失其值。因此,我们需要在删除行之前克隆值。除此之外,代码几乎相同。只需用以下内容替换最里面的条件:

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;
}