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