从菜单条中删除项目

时间:2014-08-22 12:28:10

标签: c# winforms

我在 Windows窗体中有一个带有以下结构的菜单条,名为mstMain

  • 文件
  • 程序
    • 地址
    • 联系人
      • PRG1001
      • PRG1002
    • 查询
    • 设置
      • PRG8003
  • 帮助

我正在执行for循环以移除Programs(名为mnuPrograms)中项目数为== 0的所有项目。我的尝试是:

  for (int n = 0; n < mnuPrograms.MenuItems.Count; n++)
                        if (mnuPrograms.MenuItems[n].MenuItems.Count == 0)
                            mnuPrograms.MenuItems.Remove(mnuPrograms.MenuItems[n]);

并且它不会删除正确的项目。我也使用了foreach

foreach (
     MenuItem item in
       mnuPrograms.MenuItems.Cast<MenuItem>().Where(item => item.MenuItems.Count == 0))
                        mnuPrograms.MenuItems.Remove(item);

但在这种情况下,我收到 InvalidOperationException 。我怎么能这样做?

2 个答案:

答案 0 :(得分:3)

在循环播放时,您正在修改列表。

  • for 子句中,删除项目时索引会发生变化。 尝试从结尾到开头循环遍历列表。
  • foreach 子句中,在枚举列表时修改列表会结束 使用 InvalidOperationException

pid是正确的,你可以禁用一个项而不是删除它。

答案 1 :(得分:2)

从可用性的角度来看,您可能更喜欢禁用这些项目。用户希望看到他们无法做某事。通过删除它们可能会感到困惑。禁用项目后,问题可能已经解决。

修改

你也有一个错误的假设,表示更深层次的误解。你正在做两件事:

  • 迭代一套
  • 修改集合

如果您没有设置枚举的不变,则不应该同时执行这两项操作,因为终止条件变得不可预测(在某些情况下NP不完整)。这就是为什么如果修改块内的枚举集,foreach将抛出异常。

为了避免这种情况,你应该只在不删除时增加,但此时while()更优雅,就像这样:

while (i < list.Count)
{
    // do stuff with list[i]

    if (removal_condition) // only do one of these, never both
    {
        list.RemoveAt(i);
    }
    else
    {
        i++;
    }
}