拖放Datagrid的行查看Winform C#

Rav*_*avi 1 c# datagridview

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

谢谢

TaW*_*TaW 10

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

1 - 未绑定的示例

下面是一个简单的示例,它使用鼠标事件来拖动行,同时Cell在a中叠加一个值Label.

它会在您放入的行之后插入行.

dragLabel部分是可选的..

在此输入图像描述

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

int dragRow = -1;
Label dragLabel = null;
Run Code Online (Sandbox Code Playgroud)

然后我们编码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;
}
Run Code Online (Sandbox Code Playgroud)

MouseMove我们只是移动标签.但是,由于MouseDown通常开始细胞选择,我们清除选择..

private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left && dragLabel != null)
    {
        dragLabel.Location = e.Location;
        dataGridView1.ClearSelection();
    }
}
Run Code Online (Sandbox Code Playgroud)

真正的工作是在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;
    }
}
Run Code Online (Sandbox Code Playgroud)

几点说明:

确保没有新行或修改行或您无法移动它.我花了一段时间意识到我必须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;
}
Run Code Online (Sandbox Code Playgroud)