How to find a MenuItem's name, or, there's no more Tag property

J

Jeff Mason

I have an application where I need to set certain menu items invisible based on a
user privilege.

We did a sinmlar thing in VB6 and used the menu item's tag property to assign an
identifier to each menu entry, then used that identifier as an index into a
collection populated at user login in order to determine the item's visibility.

Now, for some reason there's no tag property for .NET MenuItems, so I'm looking for
some way to accomplish what I was able to do in VB6. If I could get access to the
menu name assigned at design time that could work, but I can't see how to do that.
It's not available at run time via the menu item's type.

The sample code in help has hideous If/Then/ElseIf structures like:

If menuitem is mnuFile Then
...
elseif menuitem is mnuEdit then
...
elseif...

But there has to be a better way to uniquely identify a menuitem at run time.

I suppose I could derive a class from MenuItem and define my own tag or other
identifier property, but then I wouldn't be able to use that class in the menu
designer.

Is it possible to discover the specific instance of the menuitem via reflection
somehow?
 
H

Herfried K. Wagner [MVP]

* Jeff Mason said:
I have an application where I need to set certain menu items invisible based on a
user privilege.

We did a sinmlar thing in VB6 and used the menu item's tag property to assign an
identifier to each menu entry, then used that identifier as an index into a
collection populated at user login in order to determine the item's visibility.

Now, for some reason there's no tag property for .NET MenuItems, so I'm looking for
some way to accomplish what I was able to do in VB6. If I could get access to the
menu name assigned at design time that could work, but I can't see how to do that.
It's not available at run time via the menu item's type.

<URL:http://groups.google.de/[email protected]>
 
K

Ken Tucker [MVP]

Jeff,

The hashtable creates a table you can look up values based on a key.
The key is an object. Store the value in a hashtable with the key being the
menuitem.

Ken
 
J

Jeff Mason


Thank you for your response. Your link suggests I derive a class from MenuItem to
add a property to handle this. But, as I said in my original post:
I suppose I could derive a class from MenuItem and define my own tag or other
identifier property, but then I wouldn't be able to use that class in the menu
designer.

This is a large project with many many menu entries yet to be developed, so the menu
designer is pretty important to me.

Is there another way to identify the menu items in a form?
 
H

Herfried K. Wagner [MVP]

* Jeff Mason said:
Thank you for your response. Your link suggests I derive a class from MenuItem to
add a property to handle this. But, as I said in my original post:


This is a large project with many many menu entries yet to be developed, so the menu
designer is pretty important to me.

Is there another way to identify the menu items in a form?

Well, I don't know about an easy way to do that...
 
J

Jeff Mason

Jeff,

The hashtable creates a table you can look up values based on a key.
The key is an object. Store the value in a hashtable with the key being the
menuitem.

Ken

Hi Ken,

Thanks for the response.

Your suggestion implies that the association of "tag" information by menuitem can be
set up only at run time. Since I must be able to persist menu access privilege
information by user in a database, I'm not sure how your technique would apply. Each
user would have access defined for each menu entry, so I'm envisioning a database
table storing {User, <somekindofMenuIdentifier>, AccessRights}. At app
startup/logon, then, when I identify the User, I would retrieve his menu access
rights and modify the menu accordingly, i.e. set a given MenuItem visible/invisible
based on the rights. So the problem is in persisting <somekindofMenuIdentifier> and
then relating that back to the corresponding MenuItem object.

In VB6 we defined an arbitrary ID value as <somekindofMenuIdentifier> and stored it
in the menu's Tag property at design time. At run time, then, it was easy to
identify the particular menu entry by searching for this tag value.

But I see no good way to do the equivalent in .NET :-(

Is there any way to obtain the MenuItem's name by say, reflection?
 
M

Mick Doherty

How about creating an extender to add an Identifier property to a menu item?
You'll get the extra property and will still be able to use standard
MenuItems.
I'll just write one now and add it to the Menus section on my website.
 
J

Jeff Mason

How about creating an extender to add an Identifier property to a menu item?
You'll get the extra property and will still be able to use standard
MenuItems.
I'll just write one now and add it to the Menus section on my website.

Thank you.

I tried your MenuIdentifier class, but it didn't seem to work. Perhaps I am doing
something wrong (and I certainly don't claim to understand the extenderprovider
class), but I included your class in my project, and the "Identifier" property does
not show up on a menuitem, either at run time or design time.

Is there some other plumbing I need to hook up this extender?
 
M

Mick Doherty

Well I don't know what the problem could be since it works a treat here.
Once I drop a MenuIdentifier component on my form all the Menu Items are
extended with
Identifier On MenuIdentifier1
It was very quickly thrown together and the value is initially an empty
string. I tested it by changing the value to that of the text, but you can
change it to any string value. I then tested it wth the following code:
\\\\\\\\\\\\\\\\\\\\\\
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) _
Handles MyBase.Load
CheckMenuItems(Me.Menu)
End Sub

Sub CheckMenuItems(ByVal Menu_Item As Menu)
Dim s() As String = {"Cut", "Open"}
For Each ITEM As MenuItem In Menu_Item.MenuItems
If Array.BinarySearch(s, _
MenuIdentifier1.GetIdentifier(ITEM).ToString) >= 0 Then
ITEM.Enabled = False
End If
CheckMenuItems(ITEM)
Next
End Sub
/////////////////////////
This resulted in the Cut and Open menuitems being disabled.

Do you have a MenuIdentifier component sitting next to your MainMenu
component?
 
M

Mick Doherty

After adding the class to your project compile and then add the
MenuIdentifier to the toolbox. You can then drop one on your form at
designtime and the extended property should show up on all menuitems.
 
J

Jeff Mason

Once I drop a MenuIdentifier component on my form all the Menu Items are
extended with
Identifier On MenuIdentifier1

That was the piece I was missing. Thank you. It indeed "works a treat".
 
M

Mick Doherty

You're welcome.

I have modified the source to give a more meaningful name. You will now get
Tag on MenuTagger1.
 
J

Jay B. Harlow [MVP - Outlook]

Jeff,
This is a large project with many many menu entries yet to be developed, so the menu
designer is pretty important to me.

What I normally do is derived from MenuItem as the article suggests. Then I
carefully modify the "Windows Form Designer generated code" section to
replace all "System.Windows.Forms.MenuItem" with my derived MenuItem class.
Using "Edit - Replace in Files" if needed...

I normally reserve the property extender for when I need to add a property
to a variety of classes on a form and cannot (choose not to) extend the
individual classes...

Hope this helps
Jay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top