Before each subitem in MenuStrip

I want to get all the SubItems my MenuStrip , so I can change them all at once.

I try things like the following, but they do not work:

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

Can someone help me in coding a good foreach loop to get all SubMenuItems(DropDownItems) from MenuStrip ?

EDIT is now trying to work with the following 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 { } } 
+4
source share
8 answers

Try the following:

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

Modification of the answer Vale. Separators will not break this version, and they will also be returned (menuStripItems is ToolStripItemCollection, i.e.: this.MainMenuStrip.Items):

  /// <summary> /// Recursively get SubMenu Items. Includes Separators. /// </summary> /// <param name="item"></param> /// <returns></returns> private IEnumerable<ToolStripItem> 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); } } 

Fill out the list:

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

Complete the list:

  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 } } 
+4
source

It seems you cannot do this with the direct "foreach" approach. I think I get it.

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

Adding menu items manually to the list is a bit barbaric, but using "foreach" or "for" or other loops gave me the same error. something about listing. It seems like they cannot read all the menu items on their own: P On the other hand, if you have items like delimiters and other things, it doesn't quite look like a simple menu item, putting them all on the same list, and trying renaming will be another problem.

This is for changing the text displayed in the menu items, but you can do whatever you want with it using this method.

+2
source

You really have the wrong type, DropDownItems contains the ToolStripItem not collection of the ToolStripMenuItem collection.

Try this instead:

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

Or in your function:

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

For .net 4.5 and above, I used this to get dropdownitems for a specific toolkit.

 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 } } 
+1
source

Please note that “not working” is a very ineffective description. You must send an error message or behavior.

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

There is a good explanation for this here.

0
source

Below is the extension class to get all ToolStripMenuItem s. The advantage here is that all the code has one recursive method. It can be easily converted to a general method if other types of menu items are needed.

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

Here is a very simple solution.

 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 } } 
0
source

Source: https://habr.com/ru/post/1468918/


All Articles