Foreach every Subitem in a MenuStrip

2019-05-04 15:43发布

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

I'am trying things like the following, but they aren't working:

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

Can someone help me out coding a good foreach loop for getting all the SubMenuItems(DropDownItems) from the MenuStrip?

EDIT 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
            {

            }
        }

8条回答
做个烂人
2楼-- · 2019-05-04 15:44

You've actually got the type wrong, DropDownItems contains a collection of ToolStripItem not a collection of ToolStripMenuItem.

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);
        }
    }
}
查看更多
走好不送
3楼-- · 2019-05-04 15:47

Below is an extension class to get all ToolStripMenuItems. The advantage here is that all code is in one recursive method. One can easily convert this to a generic method if other menu item types 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;
    }
}
查看更多
beautiful°
4楼-- · 2019-05-04 15:49

Try this:

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;
    }
}
查看更多
爷、活的狠高调
5楼-- · 2019-05-04 15:55

It seems you cannot do it with direct 'foreach' approach. I think I figured it out.

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 a list is a bit barbarian, but using 'foreach' or 'for' or other cycles gave me the same error. something about enumeration. It seems like they cannot count all the menu items by themselves :P On the other hand, if you have items like seperators and other stuff, that is not quite like a simple menu item, putting them all in one list and trying to rename would raise another problem.

This is for changing the text displayed on menu items, but you can do absolutely anything you want with them using this method.

查看更多
迷人小祖宗
6楼-- · 2019-05-04 15:56

For .net 4.5 and above I've used this to get dropdownitems for a specific toolstripmenuitem.

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
        }
    }
查看更多
对你真心纯属浪费
7楼-- · 2019-05-04 15:59

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
    }

}
查看更多
登录 后发表回答