6

我想得到我所有的SubItemsMenuStrip所以我可以一次改变它们。

我正在尝试以下方法,但它们不起作用:

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

有人可以帮我编写一个好的代码foreach loop来获得所有SubMenuItems(DropDownItems)的东西MenuStrip吗?

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

8 回答 8

6

尝试这个:

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;
    }
}
于 2013-03-13T09:58:06.773 回答
5

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

填充列表:

    List<ToolStripItem> allItems = new List<ToolStripItem>();
    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
          }
     } 
于 2013-10-08T21:04:36.380 回答
2

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

List<ToolStripMenuItem> l = new List<ToolStripMenuItem> { };
        l.Add(menuItem1);
        l.Add(menuItem2);

        foreach (ToolStripMenuItem m in l)
        {
            m.Text = "YourTextHere";
        }

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

这是用于更改菜单项上显示的文本,但您可以使用此方法对它们进行任何您想要的操作。

于 2013-03-13T09:21:54.333 回答
1

你实际上弄错了类型,DropDownItems包含一个集合而ToolStripItem 不是一个集合ToolStripMenuItem

试试这个:

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

或者在你的函数中:

private void SetToolStripItems(ToolStripItemCollection dropDownItems)
{
    foreach (ToolStripItem item in dropDownItems)
    {
        if (item.HasDropDownItems)
        {
            SetToolStripItems(item.DropDownItems);
        }
    }
}
于 2013-03-13T09:08:36.977 回答
1

对于 .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
        }
    }
于 2015-06-16T18:29:29.477 回答
0

下面是一个获取所有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;
    }
}
于 2015-02-05T11:23:41.373 回答
-1

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

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

这里有一个很好的解释

于 2013-03-13T09:05:52.237 回答
-1

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

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
    }

}
于 2016-08-28T07:54:40.297 回答