Resolved Get text of specific ToolStrip menu item

MPIon

Well-known member
Joined
Jun 13, 2020
Messages
73
Location
England
Programming Experience
10+
I am working with WinForms, Net 7, c# 11

I have a ToolStripMenuItem with several drop down items. e.g.
C#:
     Main Menu Item
            Drop Down Item 1
            Drop Down Item 2
            etc
All I want to do is get the text shown on one of the drop down menu items. e.g. if I asked for item 2, it would give me "Drop Down Item 2"

I am sure this must be simple, but there does not seem to be a suitable property available. I have searched the internet and can't find a solution, nor is it fathomable in the Microsoft documentation.

p.s. When I want this, all I know is the index of the item, not it's name. I could do something simple like storing the text of the current item and using that,
but I thought this would be a more elegant solution if I can find one.
 
Last edited by a moderator:
Windows has an elegant solution. A solution that most people who have not done Win32 API programming tend to overlook.

Recall that the sender parameter of the event handler is not just there for show. If cast that sender from an object back to a ToolStripDropdownItem (or one of its parent object classes), you can access the Text property which is what you are looking for.

 
Windows has an elegant solution. A solution that most people who have not done Win32 API programming tend to overlook.

Recall that the sender parameter of the event handler is not just there for show. If cast that sender from an object back to a ToolStripDropdownItem (or one of its parent object classes), you can access the Text property which is what you are looking for.


Yes, but unfortunately, I do not have the sender. I am trying to find the Text from a totally different part of the code, not in response to a click event on the "Main Menu Item" toolbar.
I am sure there must be a way to find the text for the 'n'th item of the ToolStrip drop down.

I was hoping this would be just a one line solution, but might just be easier to save the text string and recall it later.
 
If you populated that drop-down list, then you know what items you put in it and what order you put them in. Therefore you would know what is at a particular index. That is assuming that you are following modern programming practices where the data Model is separate from the View, and the View is only used to visualize the Model, not hold the Model. This is the basis of all the MV* design patterns: MVC, MVVM, MVP, etc.

Anyway, I am quite sure that you can ask the toolstrip drop-down to give you back the list or array of its child items. You can index into that.

 
Last edited:
DropDownItems property returns a ToolStripItemCollection, that can indexed by index (int) or name (string). When you have the ToolStripItem get the Text property.
 
If you populated that drop-down list, then you know what items you put in it and what order you put them in. Therefore you would know what is at a particular index. That is assuming that you are following modern programming practices where the data Model is separate from the View, and the View is only used to visualize the Model, not hold the Model. This is the basis of all the MV* design patterns: MVC, MVVM, MVP, etc.

Anyway, I am quite sure that you can ask the toolstrip drop-down to give you back the list or array of its child items. You can index into that.


Yes, I did populate the items and I do know exactly what is in them and I know what is at any particular index. What I am having trouble with is getting the exact syntax for code to get back the Text for any particular item. As you say "ask the toolstrip drop-down to give you back the list or array of its child items. You can index into that." That's what I don't know how to do and can't find any examples of.

Anyway, as I say, I have a simple workaround of saving the Text of the last item clicked and using that elsewhere.
 
What I am having trouble with is getting the exact syntax for code to get back the Text for any particular item.

Why do you need to get back from the item. As you said, "I know exactly is in them and I know what is an any particular index." Therefore that means that you have the data outside of the the item and you are following modern programming best practices of having the model separate from the view. You can therefore index directly into your Model. No need to index into your View.
 
Thanks for all the help and I much appreciate people responding to this and taking the time to do so. However, no one so far has actually answered the question I asked, which I thought was fairly simple. Don't get all this Model / View stuff (where is the model anyway? - there's just code, back end and front end), but basically the text for the ToolStrip DropDown items is populated at the design stage (by myself of course).
Obviously I can get the text in the c# code by using ToolStripName.Text, but at the point in the code I need the text, I do not know the DropDown item name, just its index e.g. second one in the list.
I thought the answer would be something along the lines of ToolStripName.DropDownItems[index].Text or something like that.

It must be something similar to when you want to get the text for an item at an indexed position in a list box.

John H might be on to something with ToolStripItemCollection, that can indexed by index (int) or name (string). Can't figure out how to do that yet though.
 
Last edited:
C#:
var theText = item.DropDownItems[1].Text
Same as indexing an item in an array... 😋
 
C#:
var theText = item.DropDownItems[1].Text
Same as indexing an item in an array... 😋

Thanks John, that works, Knew it would be simple. You get the Cigar this time. Actually that's exactly what I put in my last post by purest of luck, with the correct spelling, but I had not tried that yet.
 
Thanks John, that works, Knew it would be simple. You get the Cigar this time. Actually that's exactly what I put in my last post by purest of luck, with the correct spelling, but I had not tried that yet.

One thing to be careful with this as I have just discovered, is if you have Separators in your Drop Down items.
If you are using an Enum for the items in the list, you also have to include a dummy item for each separator, otherwise the Enum value won't always match with the index to the Drop Down Item.
 
Yes because the separators are items as well.
 
If you are using an Enum for the items in the list, you also have to include a dummy item for each separator, otherwise the Enum value won't always match with the index to the Drop Down Item.

Please tell me you don't mean that you're adding dummy values to the enum type so that it matches your UI. That would be terrible. You don't mangle your data model to match your UI.

Instead of using menu item indexes to directly identify enum values, how about assigning the enum value to the Tag property of the menu item? Alternatively, create a Dictionary where the keys are the menu items and the values are the enum values. The index of the menu item is then irrelevant in both cases.
 
Both jmc's suggestions there (Tag and Dictionary) were my first thoughts too..Also, don't forget you can find controls by name so if you have eg an enum value of 1 which is "Active", and you have a tool strip menu item called ActiveToolStripMenuItem you can get the relevant tsmi from the containing one with something like:

C#:
   var e = MyEnum.Active;
   var matchingItems = mainMenu.DropDownItems.FindByName($"{e}ToolStripMenuItem", searchAllChildren: false);

The enum e is ToString()ed to produce "ActiveToolStripMenuItem" then the menu item's drop down collection is searched for a TSMI with that name. Keep your names unique across containers (if you're nesting and having searchAllChildren true) so the array that returns has only one item and you can take the first item with matchingItems[0].

Remember that you are in full design time control of the enum names and the TsMI names so it's incumbent on you to make sure they match. If the UI is being built by enumerating the enum, ensure you set the control's name to the enum name (tostring the enum) plus "ToolStripMenuItem" when you create the control
 
Last edited:
Please tell me you don't mean that you're adding dummy values to the enum type so that it matches your UI. That would be terrible. You don't mangle your data model to match your UI.

Instead of using menu item indexes to directly identify enum values, how about assigning the enum value to the Tag property of the menu item? Alternatively, create a Dictionary where the keys are the menu items and the values are the enum values. The index of the menu item is then irrelevant in both cases.

I did think about that, but I agree it is a bad idea. Instead I assigned values to the enum to match the index in the menu item. I don't think your idea of assigning values to the tag property of the menu would work for me, as I still need to find the name of the menu item from the c# code using the index from the enum.

Anyway, my method is simple and works for me. Don't care about data models or views. As far as I am concerned, its all one integrated project, front end and back end.
 

Latest posts

Back
Top Bottom