ToolStripMenuItems - How do i set a string as a variable name at runtime?

glow360

Member
Joined
Jun 5, 2006
Messages
6
Programming Experience
Beginner
I have a situation where I do not know the amount of ToolStripMenuItems to instantiate until runtime where the user will input the amount. Preferably I would not like to precreate a large amount of instances.

If I can set a string as a variable name at runtime then the prob will b solved.

is that possible n how to go bout doin it?
Thanks!
 
Strings are strings and identifiers are identifiers and the two are NOT interchangeable. There is a way to do what you ask, called reflection, but it is relatively complex and labour-intensive for both you and your application and I guarantee you that it is not necessary to accomplish your aim. You can quite easily create as many menu items as you want at run time and connect them to methods to handle their events. An example would be a most recently used (MRU) list. You cannot populate it until run time and it will change over the course of a session, but there is no issue creating the menu items and handling their Click events to open the corresponding file without ever having to resort to identifying a menu item using a string. Perhaps you should give a little more detail about exactly what you're trying to accomplish. I also strongly recommend that you read the documentation for the constructors of the ToolStripMenuItem class, some of which allow you to specify a Click event handler, and also the AddHandler statement.
 
Help...

Basically I have created 2 arrays with the size inputed by the user at runtime, then using loops instantiate the required amount of ToolStripMenuItem.

Now my next problem is how to attached event handlers for each of the menus. Sorry if this questions sounds too basic but Im new with VB.net and am being rushed by my manager to research on this so hopefully i can save some time with the right guidance (eg. creating a handler class etc etc)

My code is below:
VB.NET:
[SIZE=2][COLOR=#0000ff]Public[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Class[/COLOR][/SIZE][SIZE=2] Form1
[/SIZE][SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2] array1() [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] ToolStripMenuItem
[/SIZE][SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2] array2() [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] ToolStripMenuItem
[/SIZE][SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] Button1_Click([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.Object, [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.EventArgs) [/SIZE][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][SIZE=2] Button1.Click
[/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] count1 [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Integer
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] count2 [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Integer
[/COLOR][/SIZE][SIZE=2]count1 = Convert.ToInt32(TextBox1.Text)
count2 = Convert.ToInt32(TextBox2.Text)
[/SIZE][SIZE=2][COLOR=#0000ff]ReDim[/COLOR][/SIZE][SIZE=2] array1(count1)
[/SIZE][SIZE=2][COLOR=#0000ff]ReDim[/COLOR][/SIZE][SIZE=2] array2(count2)
[/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] i [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Integer
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] j [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Integer
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]For[/COLOR][/SIZE][SIZE=2] i = 1 [/SIZE][SIZE=2][COLOR=#0000ff]To[/COLOR][/SIZE][SIZE=2] count1
array1(i) = [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] ToolStripMenuItem
array1(i).Name = i
array1(i).Text = i
[/SIZE][SIZE=2][COLOR=#0000ff]For[/COLOR][/SIZE][SIZE=2] j = 1 [/SIZE][SIZE=2][COLOR=#0000ff]To[/COLOR][/SIZE][SIZE=2] count2
array2(j) = [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] ToolStripMenuItem
array2(j).Name = i & [/SIZE][SIZE=2][COLOR=#800000]","[/COLOR][/SIZE][SIZE=2] & j
array2(j).Text = i & [/SIZE][SIZE=2][COLOR=#800000]","[/COLOR][/SIZE][SIZE=2] & j
array1(i).DropDownItems.Add(array2(j))
 
[/SIZE][SIZE=2][COLOR=#008000]'>>>>>>>>STUCK HERE!!! NEED TO ADD HANDLERS!!!!!!!!!!!!!!!!!!!!!!!
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Next[/COLOR][/SIZE][SIZE=2] j
ContextMenuStrip1.Items.Add(array1(i))
[/SIZE][SIZE=2][COLOR=#0000ff]Next[/COLOR][/SIZE][SIZE=2] i
[/SIZE][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub
End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Class
[/COLOR][/SIZE]
 
Last edited by a moderator:
You should use the constructors that have arguments rather than setting all your properties seperately. The ToolStripMenuItem has eight overloads. They allow you to specify various properties at the time you create the object, including Name, Text, Image, DropDownItems and Click event handler. You should explore the possiblilites and use the constructor that is best in each case. Intellisense can give give a fair bit of the information as you type, or you can go to the MSDN library for more. Note that you must write the method that will hanlde the Click events at design time. The 'sender' argument of the event handler is always a reference to the object that raised the event. The MSDN help topics for the relevant constructors will have more information.
 
dude, youre writing code that is full of bland names like array1, array2, menustrip1, button1

dont you ever change your variable names so you know what stuff is? it helps us too.. if we see a variable name like:

tsmiMostRecentFiles

then we can probably guess that youre making a "most recently opened files" list, but if we see:

toolstripitem14

well, we cant really make any guesses!

basically, we're here to help you, for free - you can make our lives easier and make us want to help you by giving us a good idea of the problem. think of it as your obligation to us.. its a shared system whereby we have knowledge, you want some, you need to make a little leap of effort in giving us an idea of what knowledge you want (and maybe if it works, a little thanks too :) )
 
cjard - does it really matter? THe problem seems crystal clear: how to attach event handlers to a dynamicaly created toolstripmenuitem? As for the names, I do this samething all the time - especialy when I'm testing out theories or trying some new trick. Granted, I'd never do this in production code, but in my test apps, this kind of naming is used all the time.

glow360 - what you will want to read up on is the AddHAndler function. It takes an object's event - array1(i).Click in your case - and hooks it up to a function that will handle the even for you - just make sure the sub's signature matches the proper event signature (has the right parameters).

Once inside that event, one of the parameters sent in is a Sender of type object. Cast that to a ToolStripMenuItem and you can use any of it's properties to see which one was clicked, and act appropriatly.

-tg
 
TechGnome said:
cjard - does it really matter?

mmmh, yeah.. imho it does...

THe problem seems crystal clear: how to attach event handlers to a dynamicaly created toolstripmenuitem?

if the code was like.. nice, I'd have written an addition to it that did just that and added some supporting comments, but cause it's an undocumented mess I'm put off even looking at it..
 
Creating menu items and associating a method with the Click event is so easy it's laughable:
VB.NET:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim menuItem As New ToolStripMenuItem("Menu Item Text", Nothing, AddressOf ToolStripMenuItem_Click)

    Me.FileToolStripMenuItem.DropDownItems.Add(menuItem)
End Sub

Private Sub ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    Dim clickedMenuItem As ToolStripMenuItem = DirectCast(sender, ToolStripMenuItem)

    MessageBox.Show("You clicked the menu item named " & clickedMenuItem.Text)
End Sub
 
Creating menu items and associating a method with the Click event is so easy it's laughable:

It's laughable when you know how to do it! Since most people are asking how to do it I'd suppose for them it's not easy. I do appreciate the fact it is easy for you and once we all learn how to do it as well then we can all laugh about it.

I'd like to know why I can't remove my menu once I've created it.

Here's my code to create it once I've opened a child window.

VB.NET:
[SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] frmMain_MdiChildActivate([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Object[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.EventArgs) [/SIZE][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].MdiChildActivate
[INDENT][/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] menuItem [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] ToolStripMenuItem([/SIZE][SIZE=2][COLOR=#a31515]"Menu Item Text"[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#0000ff]Nothing[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#0000ff]AddressOf[/COLOR][/SIZE][SIZE=2] mnuWindowCloseOpenRecords_click)
[/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] Sep [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] ToolStripSeparator
[/INDENT]
[INDENT][/SIZE][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][SIZE=2] nWindow = 1 [/SIZE][SIZE=2][COLOR=#0000ff]Then
[/COLOR][/SIZE][SIZE=2][INDENT]ToolStripManager.Merge([/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].ActiveMdiChild.Controls([/SIZE][SIZE=2][COLOR=#a31515]"ToolStrip1"[/COLOR][/SIZE][SIZE=2]), ToolStrip2)
menuItem.Name = [/SIZE][SIZE=2][COLOR=#a31515]"mnuWindowSep"
[/COLOR][/SIZE][SIZE=2]menuItem.Text = [/SIZE][SIZE=2][COLOR=#a31515]""
[/COLOR][/SIZE][SIZE=2]mnuWindow.DropDownItems.Add(Sep)
menuItem.Name = [/SIZE][SIZE=2][COLOR=#a31515]"mnuWindowCloseOpenRecords"
[/COLOR][/SIZE][SIZE=2]menuItem.Text = [/SIZE][SIZE=2][COLOR=#a31515]"Close All Open Records..."
[/COLOR][/SIZE][SIZE=2]mnuWindow.DropDownItems.Add(menuItem)
[/INDENT][/SIZE][SIZE=2][COLOR=#0000ff]Else
[/COLOR][/SIZE][SIZE=2][INDENT]menuItem.Name = [/SIZE][SIZE=2][COLOR=#a31515]"mnuWindowCloseOpenRecords"
[/COLOR][/SIZE][SIZE=2]menuItem.Text = [/SIZE][SIZE=2][COLOR=#a31515]"Close All Open Records..."
[/COLOR][/SIZE][SIZE=2]mnuWindow.DropDownItems.Remove(menuItem)
[/INDENT][/SIZE][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
[/INDENT][SIZE=2][COLOR=#0000ff]
[/COLOR][/SIZE]

Here's my code to remove it once it's done it's job and I've Closed all the children windows.

VB.NET:
[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff][/COLOR][/SIZE] 
[SIZE=2][COLOR=#0000ff][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] mnuWindowCloseOpenRecords_click([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.Object, [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.EventArgs)
[INDENT][/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] indx [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Integer
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] menuItem [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] ToolStripMenuItem([/SIZE][SIZE=2][COLOR=#a31515]"Menu Item Text"[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#0000ff]Nothing[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#0000ff]AddressOf[/COLOR][/SIZE][SIZE=2] mnuWindowCloseOpenRecords_click)
[/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] Sep [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] ToolStripSeparator[/SIZE]
[SIZE=2] 
[/SIZE][SIZE=2][COLOR=#0000ff]For[/COLOR][/SIZE][SIZE=2] indx = 0 [/SIZE][SIZE=2][COLOR=#0000ff]To[/COLOR][/SIZE][SIZE=2] nWindow - 1
[INDENT][/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].MdiChildren(indx).Close()
[/INDENT][/SIZE][SIZE=2][COLOR=#0000ff]Next[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff] 
[/COLOR][/SIZE][SIZE=2]menuItem.Name = [/SIZE][SIZE=2][COLOR=#a31515]"mnuWindowSep"
[/COLOR][/SIZE][SIZE=2]menuItem.Text = [/SIZE][SIZE=2][COLOR=#a31515]""
[/COLOR][/SIZE][SIZE=2]mnuWindow.DropDownItems.Remove(Sep)
 
MenuItem.Name = [/SIZE][SIZE=2][COLOR=#a31515]"mnuWindowCloseOpenRecords"
[/COLOR][/SIZE][SIZE=2]MenuItem.Text = [/SIZE][SIZE=2][COLOR=#a31515]"Close All Open Records..."
[/COLOR][/SIZE][SIZE=2]mnuWindow.DropDownItems.Remove(MenuItem)
[/INDENT][/SIZE][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff][/COLOR][/SIZE] 
[SIZE=2][COLOR=#0000ff]

It's adds the separator and new menuitem fine but I cannot remove them.
[/COLOR][/SIZE]
 
My implication was that the mechanism provided makes the job easy, not that everyone should inherently know how to do it. Having said that, if you take notice of Intellisense and use the help documentation then it's not too hard to find out.

You aren't removing any existing menu items. Your menu contains several menu items. You are creating two new menu items and then telling the menu to remove them. They aren't part of the menu so nothing happens, and your existing menu items are unaffected. The fact that you're giving these new items the same Name as the existing items doesn't mean that they ARE the existing items. If you had some people in a group and you wanted to remove one of them, would getting another person with the same name and clothing as someone in the group help you remove anyone from the group? No it wouldn't, because while they may have the same name and the same clothes they are still two completely distinct people. The same is true of your menu items. Just because two menu items have the same Name and Text doesn't make them the same menu item.

So, you need to find the menu items you want first, then remove them. I think you'll find that the DropDownItems.RemoveByKey will remove the item with a specific name.
 
Back
Top