我的Win窗体上有一个按钮,该按钮会遍历DataGridView的每一行,并根据需要调用另一个函数。
循环和函数起作用,但是,它似乎正在跳过行。我连续选择了6行,仅处理了3行(在该函数的末尾,该行删除了该行,在6行中仅删除了3行)。
我确认循环仅调用6次函数中的3次,所以问题似乎出在循环上。
世界上正在发生什么?
这是按钮代码:
const img_default = require('http://localhost:3001/myproject/public/img-default.png')
这是被调用的函数:
private void btnProcess_Click(object sender, EventArgs e) {
foreach (DataGridViewRow row in gridData.Rows) {
// If Approved to Buy
if (Convert.ToBoolean(row.Cells["Approve"].EditedFormattedValue) == true) {
if (row.Cells["Action"].Value.ToString() == "Buy") {
ApprovedBuyAction(row.Index);
}
}
}
} // End btnPurchase Function
答案 0 :(得分:2)
我认为,这是造成ApprovedBuyAction()
末尾的罪魁祸首:
gridData.Rows.RemoveAt(rowNum);
在迭代时似乎要从集合中删除行:删除项目0,那么以前的项目1现在为项目0。在下一次迭代中,您移至新的项目1,以前是项目2。
我很惊讶您毫无例外地摆脱了这一困境。
我建议您在dataGrid.Rows
循环中,仅列出要删除的行索引。该循环结束后,循环遍历索引列表,并将每个索引依次传递到ApprovedBuyAction(idx);
。
您还可以遍历集合的临时副本:
foreach (var row in gridData.Rows.Cast<DataGridViewRow>().ToList())
{
...或者相反,正如Rufus建议的那样。当选择for
时,我更喜欢避免foreach
循环,因为当没有索引时,我不必考虑索引。但是for
循环对我来说也不是火箭科学。三种方法中的任何一种都将起作用。
答案 1 :(得分:2)
这里出现的问题是,当您遍历数据网格时,它们正在从数据网格中删除它们。通常,如果要在迭代集合时从集合中删除项目,则应从最后一个索引开始,再移至第一个索引,以避免出现这种情况(当删除一个项目时,以下所有项目的索引都会更改-1
。
例如,您可以将foreach
代码替换为以下内容以向后浏览各行:
private void btnProcess_Click(object sender, EventArgs e)
{
for (int i = gridData.Rows.Count - 1; i > -1; i--)
{
DataGridViewRow row = gridData.Rows[i];
// rest of code remains unchanged
}
}