ContextMenu: Dynamically adding sub menu items

T

tmaster

When I try to dynamically add a second sub menu item to this ContextMenu
item, I get an error 'Specified argument was out of the range of valid
values'.

Private Sub mnuTopics_Show_Select(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles mnuTopics_Show.Select

Dim mShowMenuItem As MenuItem
mShowMenuItem = DirectCast(sender, MenuItem)
mShowMenuItem.MenuItems.Clear()

' The first sub menu item gets added withouot any errors:
Dim mSubMenuItem As New MenuItem()
mSubMenuItem.Text = "Sub Item #1"
mSubMenuItem.Enabled = True
mSubMenuItem.Visible = True
AddHandler mSubMenuItem.Click, AddressOf MenuClickhandler
mShowMenuItem.MenuItems.Add(mSubMenuItem)

' This second sub menu item causes a problem:
mSubMenuItem.Text = "Sub Item #2"
mSubMenuItem.Enabled = True
mSubMenuItem.Visible = True
AddHandler mSubMenuItem.Click, AddressOf MenuClickhandler
'error occurs here:
mShowMenuItem.MenuItems.Add(mSubMenuItem)

End Sub

What am I doing wrong?
Thanks
 
A

Armin Zingler

tmaster said:
When I try to dynamically add a second sub menu item to this
ContextMenu item, I get an error 'Specified argument was out of the
range of valid values'.

Private Sub mnuTopics_Show_Select(ByVal sender As System.Object,
_
ByVal e As System.EventArgs) _
Handles mnuTopics_Show.Select

Dim mShowMenuItem As MenuItem
mShowMenuItem = DirectCast(sender, MenuItem)
mShowMenuItem.MenuItems.Clear()

' The first sub menu item gets added withouot any errors:
Dim mSubMenuItem As New MenuItem()
mSubMenuItem.Text = "Sub Item #1"
mSubMenuItem.Enabled = True
mSubMenuItem.Visible = True
AddHandler mSubMenuItem.Click, AddressOf MenuClickhandler
mShowMenuItem.MenuItems.Add(mSubMenuItem)

' This second sub menu item causes a problem:
mSubMenuItem.Text = "Sub Item #2"
mSubMenuItem.Enabled = True
mSubMenuItem.Visible = True
AddHandler mSubMenuItem.Click, AddressOf MenuClickhandler
'error occurs here:
mShowMenuItem.MenuItems.Add(mSubMenuItem)

End Sub

What am I doing wrong?

You create only one menu item but you add it twice. This is not possible.
You have to create two menu items:

'...
' This second sub menu item causes a problem:
mSubMenuItem = New MenuItem()
mSubMenuItem.Text = "Sub Item #2"

'...
 
T

tmaster

Thanks for your help. I am still having a problem with adding the second
sub menu item. If I add only one item (either one), it works fine. When I
add the 'Add second sub menu item' paragraph, then neither of the sub menu
items appear. (However, I do see the 'arrow' indicating that there are sub
items). Here is the code:

Private Sub mnuTopics_Show_Select(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles mnuTopics_Show.Select

Dim mShowMenuItem As MenuItem
mShowMenuItem = DirectCast(sender, MenuItem)
mShowMenuItem.MenuItems.Clear()

Dim mSubMenuItem As MenuItem

' Add first sub menu item. Works fine if I don't add a second sub
menu item.
mSubMenuItem = New MenuItem()
mSubMenuItem.Text = "Sub Item #1"
mSubMenuItem.Enabled = True
mSubMenuItem.Visible = True
AddHandler mSubMenuItem.Click, AddressOf MenuClickhandler
mShowMenuItem.MenuItems.Add(mSubMenuItem)

' Add second sub menu item. Now, cannot see either sub menu items.
(?)
mSubMenuItem = New MenuItem()
mSubMenuItem.Text = "Sub Item #2"
mSubMenuItem.Enabled = True
mSubMenuItem.Visible = True
AddHandler mSubMenuItem.Click, AddressOf MenuClickhandler
mShowMenuItem.MenuItems.Add(mSubMenuItem)

End Sub

Thanks again.
 
A

Armin Zingler

tmaster said:
Thanks for your help. I am still having a problem with adding the
second sub menu item. If I add only one item (either one), it works
fine. When I add the 'Add second sub menu item' paragraph, then
neither of the sub menu items appear. (However, I do see the 'arrow'
indicating that there are sub items). Here is the code:

Private Sub mnuTopics_Show_Select(ByVal sender As System.Object,
_
ByVal e As System.EventArgs) _
Handles mnuTopics_Show.Select


Handle the Popup event instead.
 
T

tmaster

I get the same results.
The 'Select' event will show one sub menu item if only one if Added. It
shows neither when two are Added.
The 'Popup' event shows niether one nor two sub options, when they are
Added.
The 'Click' event shows niether one nor two sub options, when they are
Added.
Is there something else I could be doing incorrectly?
 
A

Armin Zingler

tmaster said:
I get the same results.
The 'Select' event will show one sub menu item if only one if Added.
It shows neither when two are Added.
The 'Popup' event shows niether one nor two sub options, when they
are Added.
The 'Click' event shows niether one nor two sub options, when they
are Added.
Is there something else I could be doing incorrectly?


Sorry, my mistake! Handle the popup event of the *parent* of mnuTopics_Show.
Reason: mnuTopics_Show is shown when it's parent is opened. There you have
to fill the sub menu items of mnuTopics because the arrow is painted
depending on the count of visible sub menu items.
But, you have to change the code because you don't want to add the sub menu
items to the parent but to mnuTopics_Show itself. I tested it and it works.

If mnuTopics has no parent, it should work when handling it's popup event.
Also tested this time.
 
T

tmaster

Thanks again for your help. I think I'm getting close. As you suggest, I
handle the popup event of the *parent* of mnuTopics_Show, and, find the
'Show Type' menu option, then add the sub menu options. All works fine the
first time I access the sub menu items. But, for some reason, the sub menu
items do not appears on subsequent accesses. Here's the code:

Private Sub mnuTopics_Popup( _
ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles mnuTopics.Popup

' All of the code in this sub is dedicated to populating the
sub-menu-items
' of the 'Show Type' menu option:

' get the parent of 'Show Type' menu item:
Dim mMenu As Menu
mMenu = DirectCast(sender, Menu)

' Cycle through all of its options to find the 'Show Type' sub menu
option:
Dim mItem As MenuItem
For Each mItem In mMenu.MenuItems
If mItem.Text.ToString = "Show Type" Then
mItem.MenuItems.Clear()

Dim mSubMenuItem As MenuItem

' Add first sub menu item.
mSubMenuItem = New MenuItem()
mSubMenuItem.Text = "Sub Item #1"
mSubMenuItem.Enabled = True
mSubMenuItem.Visible = True
AddHandler mSubMenuItem.Click, AddressOf MenuClickhandler
mItem.MenuItems.Add(mSubMenuItem)

' Add second sub menu item.
mSubMenuItem = New MenuItem()
mSubMenuItem.Text = "Sub Item #2"
mSubMenuItem.Enabled = True
mSubMenuItem.Visible = True
AddHandler mSubMenuItem.Click, AddressOf MenuClickhandler
mItem.MenuItems.Add(mSubMenuItem)

End If
Next

End Sub
 
A

Armin Zingler

tmaster said:
Thanks again for your help. I think I'm getting close. As you
suggest, I handle the popup event of the *parent* of mnuTopics_Show,
and, find the 'Show Type' menu option, then add the sub menu options.
All works fine the first time I access the sub menu items. But, for
some reason, the sub menu items do not appears on subsequent
accesses. Here's the code:


I used your code but I can not reproduce the problem.

- Have you already tried to single-step through the procedure?

- Why do you search for "Show Type"? Don't you have a reference (e.g.
mnuTopicsShowType)?

- Short version of
If mItem.Text.ToString = "Show Type" Then
is
If mItem.Text = "Show Type" Then
 
T

tmaster

Regarding 'Why do you search for "Show Type"? Don't you have a reference
(e.g.mnuTopicsShowType)?'
I changed the search to a direct reference. Simplified things a bit. thanks.

Still had the problem. So, I moved the code to right before where the
ContextMenu is being invoked:
Me.mnuTopics.Show(Me.tvwTopics, New Point(e.X, e.Y))

which is in the Mouseup event of a treeview. Still had the same problem.

So I moved the code to my Initialization routine (before anything is
presented to the user). All works fine now. Problem must be related to my
trying to invoke the ContextMenu Show method from within the treeview's
mouseup event.

I really want the context sub menu items to be generated after the user
selects some node in a large treeview (based on what is currently in the
treeview). Do you have suggestions on when to lanuch the ContextMenu other
than using the MouseUp event of the TreeView?

Sorry about all of the newbie questions. I've been coding in VB6 for a good
while, but am just getting into VB.NET. By the way, I just realized that my
email address that shows for me (below) is incorrect. It should be
(e-mail address removed).

Thanks again for all of your help.
 
A

Armin Zingler

tmaster said:
Sorry about all of the newbie questions. I've been coding in VB6 for
a good while, but am just getting into VB.NET. By the way, I just
realized that my email address that shows for me (below) is
incorrect. It should be (e-mail address removed).


I'll sent you a project to this address. I hope it shows the difference to
your project because at current I don't have a solution for you (apart from
the one I sent *g*).
 
M

Mick Doherty

I've seen this before, and the solution was simple when I eventually found
it.
The cause is that you are not assigning the ContextMenu to the Control from
which it is popping up. You are either using the ContextMenu.Show method,
to popup the menu with a Left Click, or are using the TrackPopupMenu API in
order to Align the Context Menu.

Solution:
1. Remove the parent menu item from the ContextMenu.
2. Add child menuitems to the parent menu item.
3. ReInsert Parent Menuitem in the ContextMenu.

To make your dynamicmenu creation faster creat all the MenuItems in a loop
and then use addrange to add them all at once. You will see a significant
improvement in speed.

PseudoCode:
\\\
Dim mi(ItemsToAdd.Count - 1) As MenuItem 'Zero Based
For i As Integer = 0 To ItemsToAdd.Count - 1
mi(i) = New MenuItem (ItemsToAdd(i).Text, AddressOf MenuItemClick)
Next
ContextMenu.MenuItems.Remove(ParentMenuItem)
ParentMenuItem.MenuItems.Clear
ParentMenuItem.MenuItems.AddRange(mi)
ContextMenu.MenuItems.Add(ParentMenuItemIndex, ParentMenuItem)
///
 

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