在MenuStrip中预览每个Subitem

我想得到我的MenuStrip所有SubItems ,所以我可以一次更改它们。

我正在尝试以下内容,但它们无法正常工作:

 foreach (ToolStripMenuItem toolItem in menuStrip1.DropDownItems) { //Do something with toolItem here } 

有人可以帮我编写一个好的foreach loop来从MenuStrip获取所有SubMenuItems(DropDownItems)吗?

编辑现在尝试使用以下Recursive method

 private void SetToolStripItems(ToolStripItemCollection dropDownItems) { try { foreach (object obj in dropDownItems) { if (obj.GetType().Equals(typeof(ToolStripMenuItem))) { ToolStripMenuItem subMenu = (ToolStripMenuItem)obj; if (subMenu.HasDropDownItems) { SetToolStripItems(subMenu.DropDownItems); } else { } } } } catch { } } 

试试这个:

 List allItems = new List(); foreach (ToolStripMenuItem toolItem in menuStrip.Items) { allItems.Add(toolItem); //add sub items allItems.AddRange(GetItems(toolItem)); } private IEnumerable GetItems(ToolStripMenuItem item) { foreach (ToolStripMenuItem dropDownItem in item.DropDownItems) { if (dropDownItem.HasDropDownItems) { foreach (ToolStripMenuItem subItem in GetItems(dropDownItem)) yield return subItem; } yield return dropDownItem; } } 

修改Vale的答案。 分隔符不会崩溃此版本,它们也将被返回(menuStripItems是一个ToolStripItemCollection。即:this.MainMenuStrip.Items):

  ///  /// Recursively get SubMenu Items. Includes Separators. ///  ///  ///  private IEnumerable GetItems(ToolStripItem item) { if (item is ToolStripMenuItem) { foreach (ToolStripItem tsi in (item as ToolStripMenuItem).DropDownItems) { if (tsi is ToolStripMenuItem) { if ((tsi as ToolStripMenuItem).HasDropDownItems) { foreach (ToolStripItem subItem in GetItems((tsi as ToolStripMenuItem))) yield return subItem; } yield return (tsi as ToolStripMenuItem); } else if (tsi is ToolStripSeparator) { yield return (tsi as ToolStripSeparator); } } } else if (item is ToolStripSeparator) { yield return (item as ToolStripSeparator); } } 

填充列表:

  List allItems = new List(); foreach (ToolStripItem toolItem in menuStripItems) { allItems.Add(toolItem); //add sub items allItems.AddRange(GetItems(toolItem)); } 

循环列表:

  foreach(ToolStripItem toolItem in allItems) { if(toolItem is ToolStripMenuItem) { ToolStripMenuItem tsmi = (toolItem as ToolStripMenuItem); //Do something with it } else if(toolItem is ToolStripSeparator) { ToolStripSeparator tss = (toolItem as ToolStripSeparator); //Do something with it } } 

看来你不能用直接’foreach’方法做到这一点。 我想我想通了。

 List l = new List { }; l.Add(menuItem1); l.Add(menuItem2); foreach (ToolStripMenuItem m in l) { m.Text = "YourTextHere"; } 

手动将菜单项添加到列表有点野蛮,但使用’foreach’或’for’或其他循环给了我同样的错误。 关于枚举的一些事情。 看起来他们不能自己统计所有菜单项:P另一方面,如果你有像分隔符和其他东西这样的项目,那就不像一个简单的菜单项,把它们全部放在一个列表中并尝试重命名提出另一个问题。

这是用于更改菜单项上显示的文本,但您可以使用此方法完成所需的任何操作。

实际上你的类型错了, DropDownItems包含ToolStripItem的集合, 而不是 ToolStripItem的集合。

试试这个:

 foreach (ToolStripItem toolItem in menuStrip1.DropDownItems) { //do your stuff } 

或者在你的function中:

 private void SetToolStripItems(ToolStripItemCollection dropDownItems) { foreach (ToolStripItem item in dropDownItems) { if (item.HasDropDownItems) { SetToolStripItems(item.DropDownItems); } } } 

对于.net 4.5及以上版本,我使用它来获取特定工具线程的dropdownitems。

 foreach (var genreDropDownItem in this.toolStripMenuItem_AddNewShowGenre.DropDownItems) { if (genreDropDownItem is ToolStripMenuItem) //not a ToolStripSeparator { ToolStripDropDownItem genreItem = (genreDropDownItem as ToolStripDropDownItem); genreItem.Click += toolStripMenuItem_Genre_Click; //add the same click eventhandler to all dropdownitems of parent item this.toolStripMenuItem_AddNewShowGenre } } 

请注意,“不工作”是一种非常低效的描述。 您应该发布错误消息或行为。

 foreach(var item in menuStrip1.Items) { // do something with item... maybe recursively } 

这里有一个很好的解释

下面是一个扩展类,用于获取所有ToolStripMenuItem 。 这里的优点是所有代码都在一个递归方法中。 如果需要其他菜单项类型,可以轻松地将其转换为通用方法。

 public static class ToolStripItemCollectionExt { ///  /// Recusively retrieves all menu items from the input collection ///  public static IEnumerable GetAllMenuItems(this ToolStripItemCollection items) { var allItems = new List(); foreach (var item in items.OfType()) { allItems.Add(item); allItems.AddRange(GetAllMenuItems(item.DropDownItems)); } return allItems; } } 

这是一个非常简单的解决方案

 foreach (Control Maincontralls in MDIParent1.ActiveForm.Controls) //start it from the form - in this example i started with MDI form { if (Maincontralls.GetType() == typeof(MenuStrip)) // focus only for menu strip { MenuStrip ms = (MenuStrip)Maincontralls; //convert controller to the menue strip contraller type to access its unique properties foreach (ToolStripMenuItem subitem in ms.Items ) // access each items { if (subitem.Name == "loginToolStripMenuItem") subitem.Text = "Change text in loginToolStripMenuItem"; //focus controller by its name and access its properties or whatever you wants } break; //break out the loop of controller of the form coz u don't need to go through other controllers } }