在MenuStrip中预览每个Subitem

时间:2013-03-13 08:56:37

标签: c# visual-studio foreach menustrip

我希望得到SubItems的所有MenuStrip,所以我可以立即更改所有内容。

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

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
            {

            }
        }

8 个答案:

答案 0 :(得分:5)

试试这个:

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

答案 1 :(得分:4)

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

答案 2 :(得分: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另一方面,如果你有像分隔符和其他东西这样的项目,那就不像一个简单的菜单项,把它们全部放在一个列表中并尝试重命名提出另一个问题。

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

答案 3 :(得分: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);
        }
    }
}

答案 4 :(得分:1)

对于.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
        }
    }

答案 5 :(得分:0)

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

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

有一个很好的解释here

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

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

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
    }

}