问题描述:

I have a Menu Strip in Windows Forms with the following structure, named mstMain:

  • File
  • Programs

    • Address
    • Contacts
      • PRG1001
      • PRG1002
    • Query
    • Settings
      • PRG8003
  • Help

And I'm doing a for loop to remove all items in Programs (named mnuPrograms) where the number of items is == 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 (

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. How can I perform this?

网友答案:

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. That's why a foreach will throw an exception if you modify the enumerated set inside the block.

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 (i < list.Count)
{
    // do stuff with list[i]

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

You are modifiying the list while you are looping through it.

  • In the for clause, the indexes change when you remove an item. 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.

And pid is right, you may disable an item rather than delete it.

相关阅读:
Top