在 dataGridView 中删除选定行

4

我有一个 dataGridView,我用文件列表填充它。我想通过选择条目(单击)然后按下删除键来删除其中的一些条目。这是我目前拥有的代码:

private void DataGrid_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Delete)
    {
        foreach (DataGridViewRow r in DataGrid.SelectedRows)
        {
            if (!r.IsNewRow)
            {
                DataGrid.Rows.RemoveAt(r.Index);                        
            }
        }
    }
}

问题在于它把所有被点击过的行都定义为选定行。我希望删除所有高亮显示的行。换句话说,如果一行没有高亮,那么它就不是被选定的。

你尝试过检查行是否被选中吗? - Bob.
选中行和高亮行有什么区别? - nawfal
我不明白你说的那部分,如果单击一行,它就会始终被选中! - nawfal
显示初始化dgv的代码。可能来自designer.cs文件。 - nawfal
你可以尝试使用 LINQ 来执行那个操作。 - Ramgy Borja
显示剩余2条评论
7个回答

7

这应该能行

private void DataGrid_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Delete)
    {
        Int32 selectedRowCount =  DataGrid.Rows.GetRowCount(DataGridViewElementStates.Selected);
        if (selectedRowCount > 0)
        {
            for (int i = 0; i < selectedRowCount; i++)
            {
                DataGrid.Rows.RemoveAt(DataGrid.SelectedRows[0].Index);
            }
        }
    }
}

请详细说明。为什么这个会起作用?原始代码为什么不起作用? - John Saunders
两个都应该可以工作,我不确定为什么原始版本不能工作,可能是因为“DataGrid.SelectedRows”包含一个只读快照,在引用它的时候选择了时间。 - Benjamin

2
在第一个示例中,您使用DataGrid.SelectedRows作为迭代的元素,并在每次迭代后重新读取它....那个集合在每次迭代后都会减少一个...删除一个后,所选行集合将减少一个。
只需避免在迭代删除时修改集合。例如:
List<DataGridViewRow> toBeDeleted = new List<DataGridViewRow>();
try
{
    foreach (DataGridViewRow row in DataGrid.SelectedRows)
        toBeDeleted.Add(row);
    foreach (DataGridViewRow row in toBeDeleted)
        DataGrid.Rows.Remove(row);
}
catch (Exception) { }

1

由于我的声望点数不够,无法直接评论,所以John Saunders提出了一个问题,即为什么已经确定的解决方案有效而原始帖子无效 - 因为它们非常相似。
两者之间的区别在于,在原始帖子中使用了For Each语句进行迭代,这会强制对象引用到被迭代的对象上,因此如果其中一个被删除,则引用的对象将会混乱(因为它是集合,即改变了你所引用的集合)。第二个命名解决方案使用for (int i = 0; i < selected,它只是获取邮箱[i]中的单个位置(如果你愿意称之为位置)字母,因此它只处理一个对象,而不是整个集合。
你不能在For Each循环中更改集合 - 引用已经指向它,因此它是“锁定的”。


0
private: System::Void DeleteRow_Click(System::Object^ sender, System::EventArgs^ e)
{           
    /*Int32 rowToDelete = this->dataGridView1->Rows->GetFirstRow(DataGridViewElementStates::Selected);
    do {
        try{
            if (this->dataGridView1->Rows[rowToDelete]->IsNewRow){
                this->dataGridView1->Rows[rowToDelete]->Selected = false;
                rowToDelete = this->dataGridView1->Rows->GetFirstRow(DataGridViewElementStates::Selected);
            }

            this->dataGridView1->Rows->RemoveAt(rowToDelete);
        }
        catch (Exception^ e) {

        }
    } while ((rowToDelete = this->dataGridView1->Rows->GetNextRow(rowToDelete, DataGridViewElementStates::Selected)) != -1);
    */

    Int32 selectedRowCount = this->dataGridView1->Rows->GetRowCount(DataGridViewElementStates::Selected);
    for (int i = 0; i < selectedRowCount; i++)
    {
        if (this->dataGridView1->Rows[this->dataGridView1->SelectedRows[0]->Index]->IsNewRow){
            this->dataGridView1->Rows[this->dataGridView1->SelectedRows[0]->Index]->Selected = false;
            selectedRowCount = this->dataGridView1->Rows->GetRowCount(DataGridViewElementStates::Selected);
            i = -1;
        } 
        else {
            this->dataGridView1->Rows->RemoveAt(this->dataGridView1->SelectedRows[0]->Index);
        }
    }

    this->dataGridView1->ClearSelection();
}

4
请问您能否在代码中加入一些解释说明为什么这段代码可以回答问题呢?我们不鼓励只有代码而没有解释的回答,因为这样并不能教会解决方案。(另外,请问那段被注释掉的代码是干嘛用的?) - Nathan Tuggy

0
我只是使用了一个反向循环,就像这样:
private void ButtonRemoveRows_Click(object sender, EventArgs e)
{
    DataGridViewRow row;
    int length;

    length = _dataGridView.SelectedRows.Count;
    for(int i = length - 1; i >= 0; i--)
    {
        row = _dataGridView.SelectedRows[i];
        _dataGridView.Rows.Remove(row);
    }
}

这个例子是通过按钮触发而不是按键触发的,但改变很微小。可以压缩代码,删除额外的变量行和长度。


0

我试过了,这个可以。

string r1 = dataGridView1.CurrentRow.Cells[0].Value.ToString();
string r2 = dataGridView1.CurrentRow.Cells[2].Value.ToString();
string r3 = dataGridView1.CurrentRow.Cells[3].Value.ToString();
string r4 = dataGridView1.CurrentRow.Cells[4].Value.ToString();
string r5 = dataGridView1.CurrentRow.Cells[5].Value.ToString();
string r6 = dataGridView1.CurrentRow.Cells[6].Value.ToString();
string r7 = dataGridView1.CurrentRow.Cells[7].Value.ToString();
double prof = Convert.ToDouble(dataGridView1.CurrentRow.Cells[8].Value.ToString())
        / Convert.ToDouble(dataGridView1.CurrentRow.Cells[4].Value.ToString());

dataGridView2.Rows.Add(r1, rwcnt, r2, r3, r4, "", r5, r6, r7, prof);

//MessageBox.Show(prof.ToString());
dataGridView1.Rows.Remove(dataGridView1.CurrentRow); // remove current row

0
        if (dgvCustom.SelectedRows.Count > 0)
        {
            int rowCount = dgvCustom.SelectedRows.Count;

            for (int i = 0; i < rowCount; i++)   //for (int i = rowCount; i-- > 0;)
            {
                int rowIndex = dgvCustom.SelectedRows[0].Index;  //dgvCustom.SelectedRows[i].Index;

                var.RemoveAt(rowIndex);

                dgvCustom.Rows.RemoveAt(rowIndex);   //dgvCustom.Rows.Remove(dgvCustom.SelectedRows[i]);
            }
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接