Problems Converting a ContextMenu to a ContextMenuStrip

E

eBob.com

I've been working on an app which has an array of RichTextBoxes. And I have
a context menu for the RTBs. The context menu has two levels; the first
level has two items, "Load Sample Text File" and "Insert Row >"; the "Insert
Row >" item on the first level invokes, if that's the right word, a second
level which has two items, "Above" and "Below". This all worked when it was
a ContextMenu. But I am trying to change it to use the new menu classes and
I still have one unresolved problem.

Here's the code which sets up the menu ...

Dim CntxMen_rtbs As New ContextMenuStrip 'context menu for the
sample text rtbs

Dim LoadSampleTextFileMenuItem As New ToolStripMenuItem("Load Sample Text
File")
CntxMen_rtbs.Items.Add(LoadSampleTextFileMenuItem)
AddHandler LoadSampleTextFileMenuItem.Click, AddressOf
LoadSampleTextFileMenuItemClick

Dim miAB_array(1) As ToolStripMenuItem 'array of menu items for Above,
Below (for Insert Row/File)
miAB_array(0) = New ToolStripMenuItem("Above", Nothing, New
System.EventHandler(AddressOf InsertRowAbove_Click))
miAB_array(1) = New ToolStripMenuItem("Below", Nothing, New
System.EventHandler(AddressOf InsertRowBelow_Click))
Dim InsertRowMenuItem As New ToolStripMenuItem("Insert Row", Nothing,
miAB_array)
CntxMen_rtbs.Items.Add(InsertRowMenuItem)

This code results in a menu which LOOKS right, but an error here might
explain the problem I am having. (There doesn't seem to be a constructor
for ToolStripMenuItem which supports an EventHandler without an Image.)
But, as I said, this code results in a menu which looks correct.

The problem occurs in the EventHandler for the "Above" item. (I haven't
coded the "Below" item EventHandler yet.) The problem occurs in code which
is trying to determine the RTB for which the context menu was used. The
following code for the "Load Sample Text File" seems to operate correctly
....

Private Sub LoadSampleTextFileMenuItemClick(ByVal sender As Object, _
ByVal e As System.EventArgs)
Dim whichone As WhichSTrtb
Dim thertb As RichTextBox
Dim ctxmenu As ContextMenuStrip
Dim TheMenuItem As ToolStripMenuItem
TheMenuItem = DirectCast(sender, ToolStripMenuItem)
ctxmenu = DirectCast(TheMenuItem.Owner, ContextMenuStrip)
thertb = DirectCast(ctxmenu.SourceControl, RichTextBox)
whichone = DirectCast(thertb.Tag, WhichSTrtb)
MsgBox("menu item click entered for " + whichone.i.ToString + ", " +
whichone.j.ToString)

So here, finally, is the code (where the problem is) for the "Above" item
.... (similar, of course, to the code above - but it is trying to back up one
additional level ...)

Private Sub InsertRowAbove_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
MsgBox("insert row above invoked")
Dim whichone As WhichSTrtb
Dim thertb As RichTextBox
Dim ctxmenu As ContextMenuStrip
Dim TheAboveBelowMenuItem As ToolStripMenuItem
TheAboveBelowMenuItem = DirectCast(sender, ToolStripMenuItem)
Dim TheInsertRowMenuItem As ContextMenuStrip
TheInsertRowMenuItem = DirectCast(TheAboveBelowMenuItem.Owner,
ContextMenuStrip)
ctxmenu = DirectCast(TheInsertRowMenuItem.Owner, ContextMenuStrip)
'******************************
thertb = DirectCast(ctxmenu.SourceControl, RichTextBox)
whichone = DirectCast(thertb.Tag, WhichSTrtb)
MsgBox("menu item click entered for " + whichone.i.ToString + ", " +
whichone.j.ToString)
End Sub

The code as shown has an Intellisense error on the indicated statement which
says "'Owner' is not a member of 'System.Windows.Forms.ContextMenuStrip'."
That I know I could fix. But I have spent many hours already getting rid of
various Intellisense errors only to run into run time errors.

So ... if someone could tell me the right way to find the RTB in my
InsertRowAbove_Click routine I would be very grateful.

Thanks, Bob
 
E

eBob.com

eBob.com said:
I've been working on an app which has an array of RichTextBoxes. And I
have a context menu for the RTBs. The context menu has two levels; the
first level has two items, "Load Sample Text File" and "Insert Row >"; the
"Insert Row >" item on the first level invokes, if that's the right word,
a second level which has two items, "Above" and "Below". This all worked
when it was a ContextMenu. But I am trying to change it to use the new
menu classes and I still have one unresolved problem.

Here's the code which sets up the menu ...

Dim CntxMen_rtbs As New ContextMenuStrip 'context menu for the
sample text rtbs

Dim LoadSampleTextFileMenuItem As New ToolStripMenuItem("Load Sample Text
File")
CntxMen_rtbs.Items.Add(LoadSampleTextFileMenuItem)
AddHandler LoadSampleTextFileMenuItem.Click, AddressOf
LoadSampleTextFileMenuItemClick

Dim miAB_array(1) As ToolStripMenuItem 'array of menu items for Above,
Below (for Insert Row/File)
miAB_array(0) = New ToolStripMenuItem("Above", Nothing, New
System.EventHandler(AddressOf InsertRowAbove_Click))
miAB_array(1) = New ToolStripMenuItem("Below", Nothing, New
System.EventHandler(AddressOf InsertRowBelow_Click))
Dim InsertRowMenuItem As New ToolStripMenuItem("Insert Row", Nothing,
miAB_array)
CntxMen_rtbs.Items.Add(InsertRowMenuItem)

This code results in a menu which LOOKS right, but an error here might
explain the problem I am having. (There doesn't seem to be a constructor
for ToolStripMenuItem which supports an EventHandler without an Image.)
But, as I said, this code results in a menu which looks correct.

The problem occurs in the EventHandler for the "Above" item. (I haven't
coded the "Below" item EventHandler yet.) The problem occurs in code
which is trying to determine the RTB for which the context menu was used.
The following code for the "Load Sample Text File" seems to operate
correctly ...

Private Sub LoadSampleTextFileMenuItemClick(ByVal sender As Object, _
ByVal e As System.EventArgs)
Dim whichone As WhichSTrtb
Dim thertb As RichTextBox
Dim ctxmenu As ContextMenuStrip
Dim TheMenuItem As ToolStripMenuItem
TheMenuItem = DirectCast(sender, ToolStripMenuItem)
ctxmenu = DirectCast(TheMenuItem.Owner, ContextMenuStrip)
thertb = DirectCast(ctxmenu.SourceControl, RichTextBox)
whichone = DirectCast(thertb.Tag, WhichSTrtb)
MsgBox("menu item click entered for " + whichone.i.ToString + ", " +
whichone.j.ToString)

So here, finally, is the code (where the problem is) for the "Above" item
... (similar, of course, to the code above - but it is trying to back up
one additional level ...)

Private Sub InsertRowAbove_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
MsgBox("insert row above invoked")
Dim whichone As WhichSTrtb
Dim thertb As RichTextBox
Dim ctxmenu As ContextMenuStrip
Dim TheAboveBelowMenuItem As ToolStripMenuItem
TheAboveBelowMenuItem = DirectCast(sender, ToolStripMenuItem)
Dim TheInsertRowMenuItem As ContextMenuStrip
TheInsertRowMenuItem = DirectCast(TheAboveBelowMenuItem.Owner,
ContextMenuStrip)
ctxmenu = DirectCast(TheInsertRowMenuItem.Owner, ContextMenuStrip)
'******************************
thertb = DirectCast(ctxmenu.SourceControl, RichTextBox)
whichone = DirectCast(thertb.Tag, WhichSTrtb)
MsgBox("menu item click entered for " + whichone.i.ToString + ", " +
whichone.j.ToString)
End Sub

The code as shown has an Intellisense error on the indicated statement
which says "'Owner' is not a member of
'System.Windows.Forms.ContextMenuStrip'." That I know I could fix. But I
have spent many hours already getting rid of various Intellisense errors
only to run into run time errors.

So ... if someone could tell me the right way to find the RTB in my
InsertRowAbove_Click routine I would be very grateful.

Thanks, Bob
I don't know if this is progress, but the following code ...

Private Sub InsertRowAbove_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
MsgBox("insert row above invoked")
Dim whichone As WhichSTrtb
Dim thertb As RichTextBox
Dim ctxmenu As ContextMenuStrip
Dim TheAboveBelowMenuItem As ToolStripMenuItem
TheAboveBelowMenuItem = DirectCast(sender, ToolStripMenuItem)
Dim TheInsertRowMenuItem As ToolStripMenuItem
TheInsertRowMenuItem = DirectCast(TheAboveBelowMenuItem.OwnerItem,
ToolStripMenuItem)
ctxmenu = DirectCast(TheInsertRowMenuItem.Owner, ContextMenuStrip)
thertb = DirectCast(ctxmenu.SourceControl, RichTextBox)
whichone = DirectCast(thertb.Tag, WhichSTrtb) ' **** NullReferenceException
****
MsgBox("menu item click entered for " + whichone.i.ToString + ", " +
whichone.j.ToString)
End Sub

.... gets no compile time errors. However, the statement indicated produces
a NullReference. That makes sense as the debugger shows that "thertb" is
Nothing. And that makes sense since ctxmenu.SourceControl is Nothing. I
hope that this is interesting info, but it is not helping me to find my
error.

Bob
 
E

eBob.com

eBob.com said:
I don't know if this is progress, but the following code ...

Private Sub InsertRowAbove_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
MsgBox("insert row above invoked")
Dim whichone As WhichSTrtb
Dim thertb As RichTextBox
Dim ctxmenu As ContextMenuStrip
Dim TheAboveBelowMenuItem As ToolStripMenuItem
TheAboveBelowMenuItem = DirectCast(sender, ToolStripMenuItem)
Dim TheInsertRowMenuItem As ToolStripMenuItem
TheInsertRowMenuItem = DirectCast(TheAboveBelowMenuItem.OwnerItem,
ToolStripMenuItem)
ctxmenu = DirectCast(TheInsertRowMenuItem.Owner, ContextMenuStrip)
thertb = DirectCast(ctxmenu.SourceControl, RichTextBox)
whichone = DirectCast(thertb.Tag, WhichSTrtb) ' ****
NullReferenceException ****
MsgBox("menu item click entered for " + whichone.i.ToString + ", " +
whichone.j.ToString)
End Sub

... gets no compile time errors. However, the statement indicated
produces a NullReference. That makes sense as the debugger shows that
"thertb" is Nothing. And that makes sense since ctxmenu.SourceControl is
Nothing. I hope that this is interesting info, but it is not helping me
to find my error.

Bob
Well ... after many Google searches and reading until my eyes were bloodshot
I've learned that what I was trying to do just doesn't seem to be possible.
The workaround is to salt away the SourceControl in the ContextMenuStrip
Opening event. A bit of a hack in my opinion. Here's a useful thread which
probably explains the problem better than I did:
http://groups.google.com/group/micr...up:microsoft.public.dotnet.*#669d69233f6ea851
 
Top