I am using a ContextMenu
and have added some Menu
's to the MenuItems
MenuItemCollection
by doing the following:
private const string ADD_MENU_ITEM = "Add";
private const stri开发者_如何学运维ng REMOVE_MENU_ITEM = "Remove";
...
mContextMenu.MenuItems.Add(ADD_MENU_ITEM, new EventHandler(...));
mContextMenu.MenuItems.Add(REMOVE_MENU_ITEM, new EventHandler(...));
...
Now later, I would like to access the Menu
from the MenuItemCollection
based on the caption text. So something like this:
Menu m = mContextMenu.MenuItems[ADD_MENU_ITEM]; // This doesnt work
I know that I could use the index, but I feel like there should be a way to get the Menu
based on the caption name, since that is how its added.
How might I do this?
I had a similar problem. We can't go by caption, we have to enumerate through items and compare the text.
var enumerator = node.ContextMenu?.MenuItems?.GetEnumerator();
while ((bool)enumerator?.MoveNext())
{
var item = (MenuItem)enumerator.Current;
if (item.Text == command)
{
var menuItemCollection = item.MenuItems;
menuItemCollection.Remove(item);
break;
}
}
You can't do that using the existing API - you have to get creative. I know it makes sense because that's how you call the constructor, but that's just their way of saving you time when making new MenuItems, not how it's organized internally.
I might maintain a System.Collections.Generic.Dictionary whose keys are the caption strings, and values are references to the MenuItem objects, then create a wrapper function that adds the menu item to the menu and the Dictionary. Removing those Dictionary entries when the menu items change is a different exercise.
You can try (I'm assuming C#3 or higher)
mContextMenu.MenuItems.Cast<MenuItem>().FirstOrDefault(i=>i.Text == text);
On a related note, I don't know what your intentions are but you might want to take a look at the Tag
property in MenuItem
. Is is specifically made to store private data so that you don't have to rely on the caption or dictionaries to store information.
精彩评论