我有一个用文件列表填充的 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);
}
}
}
}
问题是它将选定的行定义为一次单击的所有行。我想删除所有突出显示的行。换句话说,如果一行没有突出显示,它就没有被选中。
这应该有效
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);
}
}
}
}
在第一个示例中,您使用 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) { }
由于我不能直接发表评论(声望点数),John Saunders 问了一个问题,为什么确定的解决方案应该有效而原始帖子却没有——因为它们非常相似。
两者之间的区别在于,在原始版本中,For Each 语句用于迭代,这会强制对象引用迭代对象,因此如果删除一个,引用的对象将被弄乱(因为它是一个集合,即更改集合你有参考)。第二个命名解决方案用于 (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.
您不能在 For Eaching 时更改集合 - 已经对它进行了引用,因此它被“锁定”..
我试试这个。这是有效的。
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
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();
}
我只是像这样使用反向循环:
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);
}
}
这个例子是由一个按钮而不是按键触发的,但变化是微不足道的。可以压缩代码,删除额外的变量行和长度。
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]);
}
}