简体   繁体   English

拖放Datagrid视图Winform C#行

[英]Drag and Drop Rows of Datagrid View Winform C#

I want to Drag Rows from certain position to another position in same grid view. 我想将行从特定位置拖动到同一网格视图中的另一个位置。 The Other rows should automatically adjust according to the Drag and Drop. 其他行应根据拖放自动调整。

Thank You 谢谢

I much prefer using mouse events over actual drag&drop events for this when doing d&d within an application. 在应用程序内进行d&d时,我更喜欢使用鼠标事件而不是实际的拖放事件。

1 - Unbound example 1-未绑定示例

Here is a simple example that uses the mouse events to drag rows around while diplaying one Cell value in a Label . 这是一个简单的示例,该示例使用鼠标事件在显示Label一个Cell值的同时拖动行。

It inserts the row after the one you drop it on. 它在您放置的行之后插入行。

The dragLabel part is optional.. dragLabel部分是可选的。

在此处输入图片说明

First we declare two helper variables at class level: 首先,我们在类级别声明两个帮助程序变量:

int dragRow = -1;
Label dragLabel = null;

Then we code the CellMouseDown to prepare the Label ..: 然后,我们对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;
}

In the MouseMove we just move the Label. MouseMove我们仅移动标签。 But as the MouseDown usually starts a cell selection we clear the selection.. 但是由于MouseDown通常会启动一个单元格选择,因此我们会清除选择。

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

The real work is in the MouseUp . 真正的工作在MouseUp We need a HitTest to find out which, if any, row we are on. 我们需要一个HitTest来找出我们所在的行(如果有的话)。 We also need to calculate the target row depending on the direction of the drag. 我们还需要根据拖动的方向来计算目标行。

Finally we clean up the Label .. 最后,我们清理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;
    }
}

A few notes: 一些注意事项:

Make sure no row is new or modified or you can't move it. 确保没有新的行或修改过的行,或者您不能移动它。 It took me awhile to realize that I had to switch off AllowUserToAddRows before adding the rows initially.. 我花了一段时间才意识到,在最初添加行之前,必须关闭AllowUserToAddRows

The treatment of selections is up to you. 选择的处理方式取决于您。 I chose to select the dragged row if the drop fails. 如果放置失败,我选择选择拖动的行。 And I chose to let it fail when dragging into the empty space. 我选择让它拖到空白处时失败。

Update: 更新:

2 - DataBound example 2-DataBound示例

If the DGV is data-bound you can't move the rows directly. 如果DGV是数据绑定的 ,则不能直接移动行。 Instead you need to move the rows in the DataSource . 相反,您需要移动DataSource的行。

Let's assume you have a DataTable DT . 假设您有一个DataTable DT Then you can remove rows from it and insert rows at any position. 然后,您可以从其中删除行,并在任何位置插入行。 (Quite different from SQL DBMS tables!) (与SQL DBMS表完全不同!)

Note that a DataRow loses its values once removed from the DataTable . 请注意,一旦从DataTable删除了DataRow它就会丢失其值。 Therefore we need to clone the values before we remove the row. 因此,我们需要在删除行之前克隆值。 Other than that the code is pretty much the same. 除此之外,代码几乎相同。 Simply replace the innermost condition with this: 只需用以下内容替换最里面的条件:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM