C# Foreach 菜单条中的每个子项

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15380730/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 16:35:03  来源:igfitidea点击:

Foreach every Subitem in a MenuStrip

c#visual-studioforeachmenustrip

提问by Max

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

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

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 loopfor getting all the SubMenuItems(DropDownItems)from the MenuStrip?

谁能帮我出编码好foreach loop了让所有的SubMenuItems(DropDownItems)MenuStrip

EDIT now trying to work with the following Recursive method:

编辑现在尝试使用以下内容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
            {

            }
        }

采纳答案by Vale

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;
    }
}

回答by nvoigt

Please note that "aren't working" is a very inefficient description. You should post the error message or behaviour.

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

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

There is a nice explanation of it here

有一个很好的解释here

回答by mattytommo

You've actually got the type wrong, DropDownItemscontains a collection of ToolStripItemnota collection of ToolStripMenuItem.

实际上,你已经得到了错误的类型,DropDownItems包含的集合ToolStripItem不能集合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);
        }
    }
}

回答by Mārti?? Radi??

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

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

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.

手动将菜单项添加到列表有点野蛮,但使用 'foreach' 或 'for' 或其他循环给了我同样的错误。关于枚举的东西。似乎他们自己无法计算所有菜单项 :P 另一方面,如果您有分隔符和其他东西之类的项目,那就不像一个简单的菜单项,将它们全部放在一个列表中并尝试重命名会提出另一个问题。

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

这是用于更改菜单项上显示的文本,但您可以使用此方法对它们做任何您想做的事情。

回答by Soenhay

Modification of Vale's answer. Separators will not crash this version and they will also be returned ( menuStripItems is a ToolStripItemCollection. ie: this.MainMenuStrip.Items ):

修改淡水河谷的答案。分隔符不会使这个版本崩溃,它们也会被返回( menuStripItems 是一个 ToolStripItemCollection。即: 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);
        }
    }

Populate a list:

填充一个列表:

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

Loop 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
          }
     } 

回答by Brett

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.

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

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;
    }
}

回答by Leopacman

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

对于 .net 4.5 及更高版本,我使用它来获取特定工具条菜单项的下拉项。

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

回答by Aylian Craspa

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
    }

}