Постигайте каждый подпункт в 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 ответов
Попробуй это:
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;
}
}
Модификация ответа Вале. Разделители не будут аварийно завершать работу этой версии, и они также будут возвращены ( 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
}
}
Кажется, вы не можете сделать это с прямым подходом "foreach". Я думаю, что я понял это.
List<ToolStripMenuItem> l = new List<ToolStripMenuItem> { };
l.Add(menuItem1);
l.Add(menuItem2);
foreach (ToolStripMenuItem m in l)
{
m.Text = "YourTextHere";
}
Добавление пунктов меню вручную в список является немного варварским, но использование 'foreach' или 'for' или других циклов дало мне ту же ошибку. кое-что о перечислении. Кажется, что они не могут сосчитать все элементы меню сами по себе:P С другой стороны, если у вас есть такие элементы, как разделители и другие элементы, это не совсем похоже на простой элемент меню, если поместить их все в один список и попытаться переименовать, поднять еще одну проблему.
Это для изменения текста, отображаемого в пунктах меню, но вы можете делать с ними абсолютно все, что хотите, используя этот метод.
Для.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
}
}
Вы на самом деле ошиблись с типом, 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);
}
}
}
Ниже приведен класс расширения, чтобы получить все 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;
}
}
Обратите внимание, что "не работает" - это очень неэффективное описание. Вы должны опубликовать сообщение об ошибке или поведение.
foreach(var item in menuStrip1.Items)
{
// do something with item... maybe recursively
}
Здесь есть хорошее объяснение
Вот очень простое решение
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
}
}