Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Foreach菜单中的每个子项_C#_Visual Studio_Foreach_Menustrip - Fatal编程技术网

C# Foreach菜单中的每个子项

C# Foreach菜单中的每个子项,c#,visual-studio,foreach,menustrip,C#,Visual Studio,Foreach,Menustrip,我想获得我的菜单的所有子项,这样我就可以一次更改它们 我正在尝试以下方法,但都不起作用: foreach (ToolStripMenuItem toolItem in menuStrip1.DropDownItems) { //Do something with toolItem here } 有人能帮我编写一个好的foreach循环,从菜单中获取所有子菜单项(下拉项) “立即编辑”尝试使用以下递归方法: private void SetToolStripItems(ToolStr

我想获得我的
菜单的所有
子项
,这样我就可以一次更改它们

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

foreach (ToolStripMenuItem toolItem in menuStrip1.DropDownItems)
{
      //Do something with toolItem here
}
有人能帮我编写一个好的
foreach循环
,从
菜单中获取所有
子菜单项(下拉项)

“立即编辑”尝试使用以下
递归方法

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
            {

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

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

对它有一个很好的解释

实际上您的类型错了,
下拉项
包含一个
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);
        }
    }
}

似乎你不能用直接的“foreach”方法来做。我想我明白了

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

        foreach (ToolStripMenuItem m in l)
        {
            m.Text = "YourTextHere";
        }
List l=新列表{};
l、 添加(菜单项1);
l、 添加(菜单项2);
foreach(ToolStripMenuItem m在l中)
{
m、 Text=“YourTextHere”;
}
手动将菜单项添加到列表中有点野蛮,但使用“foreach”或“for”或其他循环会产生相同的错误。关于枚举。似乎他们自己无法计算所有的菜单项:P另一方面,如果你有像分隔符和其他东西这样的项目,那就不太像一个简单的菜单项,将它们全部放在一个列表中并尝试重命名会引发另一个问题

这用于更改菜单项上显示的文本,但使用此方法,您完全可以对其执行任何操作。

尝试以下操作:

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;
    }
}
List allItems=new List();
foreach(menuStrip.Items中的ToolStripMenuItem toolItem)
{
添加(工具项);
//添加子项
allItems.AddRange(GetItems(toolItem));
}  
私有IEnumerable GetItems(ToolStripMenuItem)
{
foreach(item.DropDownItems中的ToolStripMenuItem dropDownItem)
{
if(dropDownItem.HasDropDownItems)
{
foreach(GetItems中的ToolStripMenuItem子项(dropDownItem))
收益回报子项;
}
收益率返回下拉项;
}
}

修改淡水河谷公司的答案。分隔符不会使此版本崩溃,也会返回分隔符(menuStripItems是ToolStripItemCollection.ie:this.MainMenuStrip.Items):


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

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;
    }
}
公共静态类ToolStripItemCollectionText
{
/// 
///从输入集合中重复检索所有菜单项
/// 
公共静态IEnumerable GetAllMenuItems(此ToolStripItemCollection项)
{
var allItems=新列表();
foreach(items.OfType()中的var item)
{
所有项目。添加(项目);
allItems.AddRange(GetAllMenuItems(item.DropDownItems));
}
返回allItems;
}
}

对于.net 4.5及更高版本,我使用它来获取特定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
        }
    }

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

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
    }

}

提示:您需要使用递归。我目前正试图为此找到一篇好文章……obj.GetType().Equals(typeof(ToolStripMenuItem))可以简单地编写为(obj是ToolStripMenuItem),这不是一种非常动态的方法,如果我添加一个menuItem呢?我也必须在代码中添加它,这不是我想要的。这是我说的-一种野蛮的方法,但至少它是有效的:DHaha是的,你是对的,我会为你的工作给你+1,因为它确实有效,但我需要动态更改它:)meneStrip1不包含DropDownItems集合。然后使用您的函数并将其更改为
DropDownItems
@Mobstaa检查我的更新编辑,我已添加了您函数的修订版本。没有带项的“.HasDropDownItems”:(@Mobstaa-Doh,它们必须是
ToolStripMenuItem
。运行函数时出现了什么错误?取出空的
catch
我没有收到错误消息,但它没有选择正确的子菜单项,您使用Foreach循环所做的只是获取MenuStrip的标题,而不是下拉项。您是这样做的吗广告我提供的链接?它有一个完整的解决方案,你的问题。我使用了该链接的代码,但它不工作的方法,我会给你一个大拇指为你的工作,注意:我不是那个投票反对你的人。谢谢你的大拇指。请注意,人们不能帮助“它不工作”如果您没有对问题进行更精确的描述。它不起作用,因为该方法正在选择所有菜单顶部项,但我也需要子项,如我在问题中所述:)
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;
    }
}
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
        }
    }
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
    }

}