简体   繁体   English

从菜单栏删除项目

[英]Remove item from Menu Strip

I have a Menu Strip in Windows Forms with the following structure, named mstMain : 我在Windows窗体中有一个具有以下结构的菜单条,名为mstMain

  • File 文件
  • Programs 程式
    • Address 地址
    • Contacts 往来
      • PRG1001 PRG1001
      • PRG1002 PRG1002
    • Query 询问
    • Settings 设置
      • PRG8003 PRG8003
  • Help 救命

And I'm doing a for loop to remove all items in Programs (named mnuPrograms ) where the number of items is == 0 . 我正在执行for循环,以删除Programs (名为mnuPrograms )中的所有项目,其中项目的数量为== 0 My attempt is: 我的尝试是:

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

And it doesn't remove the correct items. 而且它不会删除正确的项目。 I have used foreach too: 我也用过foreach

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

But in this case I receive a InvalidOperationException . 但是在这种情况下,我收到InvalidOperationException How can I perform this? 我该如何执行呢?

You are modifiying the list while you are looping through it. 您正在遍历列表时对其进行修改。

  • In the for clause, the indexes change when you remove an item. for子句中,删除项目时索引会更改。 Try looping through the list from the end to the start. 尝试从头到尾遍历列表。
  • In the foreach clause, modifying a list while enumerating it ends with an InvalidOperationException . foreach子句中,在枚举枚举时修改列表以InvalidOperationException结尾。

And pid is right, you may disable an item rather than delete it. 而且pid是正确的,您可以禁用一个项目而不是删除它。

On a Usability point of view, you might prefer to disable the items. 从可用性的角度来看,您可能希望禁用这些项目。 Users want to see that they cannot do something. 用户希望看到他们不能做某事。 By removing them they may get confused. 通过删除它们,他们可能会感到困惑。 Once you disable the items your problem might already be solved. 禁用项目后,您的问题可能已经解决。

EDIT: 编辑:

You also have a false assumption that denotes a deeper misunderstanding. 您也有一个错误的假设,表示存在更深的误解。 You are doing two things: 您正在做两件事:

  • iterating over a set 遍历一组
  • modifying the set 修改集合

You shouldn't do both because termination conditions become unpredictable (NP-incomplete under circumstances) if you don't have an invariant set over which you enumerate. 您不应同时执行这两种操作,因为如果您没有枚举所依据的不变集,则终止条件将变得不可预测(在某些情况下,NP会不完整)。 That's why a foreach will throw an exception if you modify the enumerated set inside the block. 这就是为什么如果您修改块内的枚举集,则foreach将引发异常的原因。

To avoid this you should increment only when you don't remove, but at that point a while() is more elegant, much like this: 为了避免这种情况,您应该仅在不删除时增加它,但那一刻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++;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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