为什么我的foreach循环仅处理彼此一个?

时间:2019-05-24 17:50:14

标签: c# winforms foreach

我的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

2 个答案:

答案 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
    }
}