简体   繁体   中英

removing selected rows in dataGridView

I have a dataGridView that I populate with a list of files. I'd like to be able to remove some of those entries by selecting the entry (by clicking it) and then pressing the delete key. Here's the code I have so far:

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

The problem is that it defines selected rows as all rows that were at one time clicked on. I would like to delete all highlighted rows. In other words, if a row is not highlighted it's not selected.

This should work

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

In the first example you use the DataGrid.SelectedRows as the elements of the iteration, and you re-read it after every iteration....

That collection goes down by one after every iteration... The selected rows collection WILL decrease after you delete one.

Just avoid modifying the collections while iterating for removal. Example:

    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) { }

Since I can not comment directly (reputation points) , John Saunders asked a question why the solution identified should work and the original post did not - since they are very similar.
The difference between the two is that in the Original a For Each statement is being used to iterate which forces object references to the iterated objected and therefore if one is removed the referenced object would be messed up (as it is a collection ie changing the collection you have referenced). The second as named solution uses for (int i = 0; i < selected which is simply getting the individual location (if you will) letter in mailbox[i], therefore it is the only object that is being dealt with and not the collection as a whole.
You can not change the collection while For Eaching what you have - the reference is already made to it and therefore it is 'locked'..


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

I just use a reverse for loop like this:

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

the example is triggered by a button and not by pressing a key, but the change is trivial. Code can be condensed removing the extra variables row and length.

I try this. This is worked.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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