|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Attach handlers to ToolStripMenuItems. Got stacked, Please HelpSub InitSomething() mSet(me.FindForm) End Sub Sub mSet(ByVal f As Control) For Each t As Control In f.Controls If TypeOf t Is ToolStripMenuItem Then AddHandler t.MouseEnter, AddressOf Me.SetSemaforoMenu End If mSet(t) Next t End Sub because I wanted to attach an handler to the MouseEnter event of all the ToolStripMenuItems which are on the form which contains this control. But this gives error because it says ToolStripMenuItem is not a control. Well how do I iterate on my ToolStripMenuItems. Is there a container or what ? -P If you search this form for my earlier post titled
"Re: tootip or microhelp for menu items", I posted code that will add event handlers for one level down. I couldn't figure out how to do it two or more levels down. Good luck. Robin S. <pamelaflue***@libero.it> wrote in message Show quoteHide quote news:1162849338.134785.23570@m73g2000cwd.googlegroups.com... > Hello. I have written the following code (this code is on a control): > > Sub InitSomething() > mSet(me.FindForm) > End Sub > > Sub mSet(ByVal f As Control) > For Each t As Control In f.Controls > If TypeOf t Is ToolStripMenuItem Then > AddHandler t.MouseEnter, AddressOf Me.SetSemaforoMenu > End If > mSet(t) > Next t > End Sub > > because I wanted to attach an handler to the MouseEnter event of all > the > ToolStripMenuItems which are on the form which contains this control. > > But this gives error because it says ToolStripMenuItem is not a > control. > Well how do I iterate on my ToolStripMenuItems. Is there a container or > what ? > > -P > RobinS ÀÛ¼º:
> If you search this form for my earlier post titled Hi Robin,> "Re: tootip or microhelp for menu items", I posted > code that will add event handlers for one level down. > I couldn't figure out how to do it two or more > levels down. thanks. For the levels there is no problem: as you can see, I am already doing recursion. My problem is to identify the container which contains the toolstripitems. It does not seem to be "controls". Are you suggesting I have to first iterate on toolstrip menu and then make recursion on toolstrip item? I must be dumb: I cannot see how to do this apparently simple thing... :( /P Show quoteHide quote > > Good luck. > Robin S. > > > <pamelaflue***@libero.it> wrote in message > news:1162849338.134785.23570@m73g2000cwd.googlegroups.com... > > Hello. I have written the following code (this code is on a control): > > > > Sub InitSomething() > > mSet(me.FindForm) > > End Sub > > > > Sub mSet(ByVal f As Control) > > For Each t As Control In f.Controls > > If TypeOf t Is ToolStripMenuItem Then > > AddHandler t.MouseEnter, AddressOf Me.SetSemaforoMenu > > End If > > mSet(t) > > Next t > > End Sub > > > > because I wanted to attach an handler to the MouseEnter event of all > > the > > ToolStripMenuItems which are on the form which contains this control. > > > > But this gives error because it says ToolStripMenuItem is not a > > control. > > Well how do I iterate on my ToolStripMenuItems. Is there a container or > > what ? > > > > -P > > The main container is a MenuStrip. Inside the menu strip, there are
ToolStripMenuItems. This gives you access to the items you can see on the menu strip. From there, you can access DropDownItems to get to the options that you see when you drop down. I haven't figured out how to get to the options that show to the right for each of the dropdown items yet. This is as far as I got: 'For each option you can see on the menu strip For each tsItem As ToolStripMenuItem in msMenuStrip.Items If tsItem.DropDownItems.Count > 0 then 'that entry has a dropdown For i as Integer = 0 to item.DropDownItems.Count - 1 Dim ddItem as ToolStripItm ddItem = item.DropDownItems(i) 'Now you can access ddItem, but I couldn't figure out ' how to get from here to the next level of dropdowns. Next End If Next You're not dumb. Nobody else answered the other post about this, and I searched google and microsoft and couldn't find anything telling how to enumerate through all of the levels of a menustrip/toolstrip. Let me know if you figure it out; I'm waiting with bated breath. Robin S. irish underscore songbird at comcast dot net ------------------------------------------------------------------------------- <pamelaflue***@libero.it> wrote in message news:1162906283.550715.305840@e3g2000cwe.googlegroups.com... RobinS ÀÛ¼º:> If you search this form for my earlier post titled Hi Robin,> "Re: tootip or microhelp for menu items", I posted > code that will add event handlers for one level down. > I couldn't figure out how to do it two or more > levels down. thanks. For the levels there is no problem: as you can see, I am already doing recursion. My problem is to identify the container which contains the toolstripitems. It does not seem to be "controls". Are you suggesting I have to first iterate on toolstrip menu and then make recursion on toolstrip item? I must be dumb: I cannot see how to do this apparently simple thing... :( /P Show quoteHide quote > > Good luck. > Robin S. > > > <pamelaflue***@libero.it> wrote in message > news:1162849338.134785.23570@m73g2000cwd.googlegroups.com... > > Hello. I have written the following code (this code is on a control): > > > > Sub InitSomething() > > mSet(me.FindForm) > > End Sub > > > > Sub mSet(ByVal f As Control) > > For Each t As Control In f.Controls > > If TypeOf t Is ToolStripMenuItem Then > > AddHandler t.MouseEnter, AddressOf Me.SetSemaforoMenu > > End If > > mSet(t) > > Next t > > End Sub > > > > because I wanted to attach an handler to the MouseEnter event of all > > the > > ToolStripMenuItems which are on the form which contains this control. > > > > But this gives error because it says ToolStripMenuItem is not a > > control. > > Well how do I iterate on my ToolStripMenuItems. Is there a container or > > what ? > > > > -P > > RobinS ha scritto:
Show quoteHide quote > The main container is a MenuStrip. Inside the menu strip, there are that would seem easy. Is this what you mean ?> ToolStripMenuItems. This gives you access to the items you can > see on the menu strip. From there, you can access DropDownItems > to get to the options that you see when you drop down. I haven't > figured out how to get to the options that show to the right for > each of the dropdown items yet. This is as far as I got: > > 'For each option you can see on the menu strip > For each tsItem As ToolStripMenuItem in msMenuStrip.Items > If tsItem.DropDownItems.Count > 0 then > 'that entry has a dropdown > For i as Integer = 0 to item.DropDownItems.Count - 1 > Dim ddItem as ToolStripItm > ddItem = item.DropDownItems(i) > 'Now you can access ddItem, but I couldn't figure out > ' how to get from here to the next level of dropdowns. > Next > End If > Next > > You're not dumb. Nobody else answered the other post about > this, and I searched google and microsoft and couldn't find > anything telling how to enumerate through all of the levels of > a menustrip/toolstrip. > > Let me know if you figure it out; I'm waiting with bated breath. Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'Visit All Context MenuStrip RecurseItems(Me.ContextMenuStrip1.Items) End Sub Sub RecurseItems(ByVal ToolStripItemCollection As ToolStripItemCollection) For Each ToolStripMenuItemChild As ToolStripMenuItem In ToolStripItemCollection Me.DoSomethingWithToolStripMenuItem(ToolStripMenuItemChild) RecurseItems(ToolStripMenuItemChild.DropDownItems) Next ToolStripMenuItemChild End Sub Sub DoSomethingWithToolStripMenuItem(ByVal ToolStripMenuItemChild As ToolStripMenuItem) MsgBox("I am on " & ToolStripMenuItemChild.Text) End Sub End Class Show quoteHide quote > > Robin S. > irish underscore songbird at comcast dot net > ------------------------------------------------------------------------------- > <pamelaflue***@libero.it> wrote in message > news:1162906283.550715.305840@e3g2000cwe.googlegroups.com... > > RobinS ÀÛ¼º: > > > If you search this form for my earlier post titled > > "Re: tootip or microhelp for menu items", I posted > > code that will add event handlers for one level down. > > I couldn't figure out how to do it two or more > > levels down. > > Hi Robin, > > thanks. For the levels there is no problem: as you can see, I am > already doing recursion. My problem is to identify the container which > contains the toolstripitems. It does not seem to be "controls". > > Are you suggesting I have to first iterate on toolstrip menu and then > make recursion on toolstrip item? I must be dumb: I cannot see how to > do this apparently simple thing... :( > > /P > > > > > > Good luck. > > Robin S. > > > > > > <pamelaflue***@libero.it> wrote in message > > news:1162849338.134785.23570@m73g2000cwd.googlegroups.com... > > > Hello. I have written the following code (this code is on a control): > > > > > > Sub InitSomething() > > > mSet(me.FindForm) > > > End Sub > > > > > > Sub mSet(ByVal f As Control) > > > For Each t As Control In f.Controls > > > If TypeOf t Is ToolStripMenuItem Then > > > AddHandler t.MouseEnter, AddressOf Me.SetSemaforoMenu > > > End If > > > mSet(t) > > > Next t > > > End Sub > > > > > > because I wanted to attach an handler to the MouseEnter event of all > > > the > > > ToolStripMenuItems which are on the form which contains this control. > > > > > > But this gives error because it says ToolStripMenuItem is not a > > > control. > > > Well how do I iterate on my ToolStripMenuItems. Is there a container or > > > what ? > > > > > > -P > > > That's cool! I had to put in a Try/Catch to pick up
the InvalidCastException error, because I have separator lines in my toolbars, and they are not ToolStripMenuItems. I'm going to send this to that other guy who was looking for this. So did you fix your problem with adding an event handler for Mouse Enter? Robin S --------------------------------- <pamelaflue***@libero.it> wrote in message news:1162941209.095687.108050@m73g2000cwd.googlegroups.com... RobinS ha scritto:Show quoteHide quote > The main container is a MenuStrip. Inside the menu strip, there are that would seem easy. Is this what you mean ?> ToolStripMenuItems. This gives you access to the items you can > see on the menu strip. From there, you can access DropDownItems > to get to the options that you see when you drop down. I haven't > figured out how to get to the options that show to the right for > each of the dropdown items yet. This is as far as I got: > > 'For each option you can see on the menu strip > For each tsItem As ToolStripMenuItem in msMenuStrip.Items > If tsItem.DropDownItems.Count > 0 then > 'that entry has a dropdown > For i as Integer = 0 to item.DropDownItems.Count - 1 > Dim ddItem as ToolStripItm > ddItem = item.DropDownItems(i) > 'Now you can access ddItem, but I couldn't figure out > ' how to get from here to the next level of dropdowns. > Next > End If > Next > > You're not dumb. Nobody else answered the other post about > this, and I searched google and microsoft and couldn't find > anything telling how to enumerate through all of the levels of > a menustrip/toolstrip. > > Let me know if you figure it out; I'm waiting with bated breath. Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'Visit All Context MenuStrip RecurseItems(Me.ContextMenuStrip1.Items) End Sub Sub RecurseItems(ByVal ToolStripItemCollection As ToolStripItemCollection) For Each ToolStripMenuItemChild As ToolStripMenuItem In ToolStripItemCollection Me.DoSomethingWithToolStripMenuItem(ToolStripMenuItemChild) RecurseItems(ToolStripMenuItemChild.DropDownItems) Next ToolStripMenuItemChild End Sub Sub DoSomethingWithToolStripMenuItem(ByVal ToolStripMenuItemChild As ToolStripMenuItem) MsgBox("I am on " & ToolStripMenuItemChild.Text) End Sub End Class Show quoteHide quote > > Robin S. > irish underscore songbird at comcast dot net > ------------------------------------------------------------------------------- > <pamelaflue***@libero.it> wrote in message > news:1162906283.550715.305840@e3g2000cwe.googlegroups.com... > > RobinS ÀÛ¼º: > > > If you search this form for my earlier post titled > > "Re: tootip or microhelp for menu items", I posted > > code that will add event handlers for one level down. > > I couldn't figure out how to do it two or more > > levels down. > > Hi Robin, > > thanks. For the levels there is no problem: as you can see, I am > already doing recursion. My problem is to identify the container which > contains the toolstripitems. It does not seem to be "controls". > > Are you suggesting I have to first iterate on toolstrip menu and then > make recursion on toolstrip item? I must be dumb: I cannot see how to > do this apparently simple thing... :( > > /P > > > > > > Good luck. > > Robin S. > > > > > > <pamelaflue***@libero.it> wrote in message > > news:1162849338.134785.23570@m73g2000cwd.googlegroups.com... > > > Hello. I have written the following code (this code is on a control): > > > > > > Sub InitSomething() > > > mSet(me.FindForm) > > > End Sub > > > > > > Sub mSet(ByVal f As Control) > > > For Each t As Control In f.Controls > > > If TypeOf t Is ToolStripMenuItem Then > > > AddHandler t.MouseEnter, AddressOf Me.SetSemaforoMenu > > > End If > > > mSet(t) > > > Next t > > > End Sub > > > > > > because I wanted to attach an handler to the MouseEnter event of all > > > the > > > ToolStripMenuItems which are on the form which contains this control. > > > > > > But this gives error because it says ToolStripMenuItem is not a > > > control. > > > Well how do I iterate on my ToolStripMenuItems. Is there a container > > > or > > > what ? > > > > > > -P > > > I am working on it. It's subtle because the contextmenu are in
components not in controls. So recursion on the form seems tricky because "components" is private (aarg!) I would not suggest to use Try catch for that. It's ugly. I will try to work out a general solution in the next minutes which consider separators too. Warn me if there are other things that should be taken cared of ... -P RobinS ha scritto: Show quoteHide quote > That's cool! I had to put in a Try/Catch to pick up > the InvalidCastException error, because I have > separator lines in my toolbars, and they are not > ToolStripMenuItems. I'm going to send this to that > other guy who was looking for this. > > So did you fix your problem with adding an event handler > for Mouse Enter? > > Robin S > --------------------------------- > > <pamelaflue***@libero.it> wrote in message > news:1162941209.095687.108050@m73g2000cwd.googlegroups.com... > > RobinS ha scritto: > > > The main container is a MenuStrip. Inside the menu strip, there are > > ToolStripMenuItems. This gives you access to the items you can > > see on the menu strip. From there, you can access DropDownItems > > to get to the options that you see when you drop down. I haven't > > figured out how to get to the options that show to the right for > > each of the dropdown items yet. This is as far as I got: > > > > 'For each option you can see on the menu strip > > For each tsItem As ToolStripMenuItem in msMenuStrip.Items > > If tsItem.DropDownItems.Count > 0 then > > 'that entry has a dropdown > > For i as Integer = 0 to item.DropDownItems.Count - 1 > > Dim ddItem as ToolStripItm > > ddItem = item.DropDownItems(i) > > 'Now you can access ddItem, but I couldn't figure out > > ' how to get from here to the next level of dropdowns. > > Next > > End If > > Next > > > > You're not dumb. Nobody else answered the other post about > > this, and I searched google and microsoft and couldn't find > > anything telling how to enumerate through all of the levels of > > a menustrip/toolstrip. > > > > Let me know if you figure it out; I'm waiting with bated breath. > > > that would seem easy. Is this what you mean ? > > > Public Class Form1 > > Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As > System.EventArgs) Handles Button1.Click > > 'Visit All Context MenuStrip > RecurseItems(Me.ContextMenuStrip1.Items) > > End Sub > > Sub RecurseItems(ByVal ToolStripItemCollection As > ToolStripItemCollection) > For Each ToolStripMenuItemChild As ToolStripMenuItem In > ToolStripItemCollection > Me.DoSomethingWithToolStripMenuItem(ToolStripMenuItemChild) > RecurseItems(ToolStripMenuItemChild.DropDownItems) > Next ToolStripMenuItemChild > End Sub > > Sub DoSomethingWithToolStripMenuItem(ByVal ToolStripMenuItemChild > As ToolStripMenuItem) > MsgBox("I am on " & ToolStripMenuItemChild.Text) > End Sub > > End Class > > > > > > > > Robin S. > > irish underscore songbird at comcast dot net > > ------------------------------------------------------------------------------- > > <pamelaflue***@libero.it> wrote in message > > news:1162906283.550715.305840@e3g2000cwe.googlegroups.com... > > > > RobinS ÀÛ¼º: > > > > > If you search this form for my earlier post titled > > > "Re: tootip or microhelp for menu items", I posted > > > code that will add event handlers for one level down. > > > I couldn't figure out how to do it two or more > > > levels down. > > > > Hi Robin, > > > > thanks. For the levels there is no problem: as you can see, I am > > already doing recursion. My problem is to identify the container which > > contains the toolstripitems. It does not seem to be "controls". > > > > Are you suggesting I have to first iterate on toolstrip menu and then > > make recursion on toolstrip item? I must be dumb: I cannot see how to > > do this apparently simple thing... :( > > > > /P > > > > > > > > > > Good luck. > > > Robin S. > > > > > > > > > <pamelaflue***@libero.it> wrote in message > > > news:1162849338.134785.23570@m73g2000cwd.googlegroups.com... > > > > Hello. I have written the following code (this code is on a control): > > > > > > > > Sub InitSomething() > > > > mSet(me.FindForm) > > > > End Sub > > > > > > > > Sub mSet(ByVal f As Control) > > > > For Each t As Control In f.Controls > > > > If TypeOf t Is ToolStripMenuItem Then > > > > AddHandler t.MouseEnter, AddressOf Me.SetSemaforoMenu > > > > End If > > > > mSet(t) > > > > Next t > > > > End Sub > > > > > > > > because I wanted to attach an handler to the MouseEnter event of all > > > > the > > > > ToolStripMenuItems which are on the form which contains this control. > > > > > > > > But this gives error because it says ToolStripMenuItem is not a > > > > control. > > > > Well how do I iterate on my ToolStripMenuItems. Is there a container > > > > or > > > > what ? > > > > > > > > -P > > > > Ok here is my complete proposal for the full problem: how to visit menu
and context menu with complete recursion everywhere. Please advise if I left out somethng or there is a better way to achieve the same result. It's possible there is some overlooking .. let me know To avoid the separer or other item error I used the general item To access components in the nested controls I used reflection, let me know in case better ways... (watch ot line breaks) Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'This visit all the items of All the MenuStrip's in all controls 'or subcontrols (got first) of this form Me.RecurseMenuStrip(Me) 'This visit all the items of All the ContextMenuStrip's in all controls 'or subcontrols of this form Me.RecurseContextMenuStrip(Me) End Sub Sub RecurseMenuStrip(ByVal Control As Control) For Each ControlChild As Control In Control.Controls If TypeOf ControlChild Is MenuStrip Then Dim MenuStrip As MenuStrip = DirectCast(ControlChild, MenuStrip) Me.RecurseToolStripItems(MenuStrip.Items) Else Me.RecurseMenuStrip(ControlChild) End If Next ControlChild End Sub Sub RecurseContextMenuStrip(ByVal Control As Control) Dim FieldInfo As System.Reflection.FieldInfo = Control.GetType.GetField("components", _ Reflection.BindingFlags.Instance Or _ Reflection.BindingFlags.NonPublic) 'for context menu in control components If FieldInfo IsNot Nothing Then Dim ControlComponents As System.ComponentModel.IContainer = DirectCast(FieldInfo.GetValue(Control), System.ComponentModel.IContainer) If ControlComponents IsNot Nothing Then For Each ControlChild As Control In ControlComponents.Components If TypeOf ControlChild Is ContextMenuStrip Then Dim ContextMenuStrip As ContextMenuStrip = DirectCast(ControlChild, ContextMenuStrip) Me.RecurseToolStripItems(ContextMenuStrip.Items) Else Me.RecurseContextMenuStrip(ControlChild) End If Next ControlChild End If End If 'for possible context menus in custom controls For Each ControlChild As Control In Control.Controls Me.RecurseContextMenuStrip(ControlChild) Next ControlChild End Sub Sub RecurseToolStripItems(ByVal ToolStripItemCollection As ToolStripItemCollection) For Each ToolStripItem As ToolStripItem In ToolStripItemCollection Me.DoSomethingWithToolStripItem(ToolStripItem) If TypeOf ToolStripItem Is ToolStripMenuItem Then Dim ToolStripMenuItem As ToolStripMenuItem = DirectCast(ToolStripItem, ToolStripMenuItem) Me.RecurseToolStripItems(ToolStripMenuItem.DropDownItems) End If Next ToolStripItem End Sub Sub DoSomethingWithToolStripItem(ByVal ToolStripItem As ToolStripItem) MsgBox("I am on " & ToolStripItem.Text) End Sub End Class I'm going to ask a stupid question here. When you say context
menus, you mean the menus that show up when you right-click on something, right? So this code will go through all the menu items on a form, whether it be in a menu strip at the top, a tool stip at the top, or a context menu assigned to a control, right? Cooooool. Robin S -------------------------- <pamelaflue***@libero.it> wrote in message Show quoteHide quote news:1162948704.245898.61110@f16g2000cwb.googlegroups.com... > Ok here is my complete proposal for the full problem: how to visit menu > and context menu with complete recursion everywhere. Please advise if I > left out somethng or there is a better way to achieve the same result. > It's possible there is some overlooking .. let me know > > To avoid the separer or other item error I used the general item > > To access components in the nested controls I used reflection, let me > know in case better ways... (watch ot line breaks) > > > > Public Class Form1 > > Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As > System.EventArgs) Handles Button1.Click > > 'This visit all the items of All the MenuStrip's in all > controls > 'or subcontrols (got first) of this form > Me.RecurseMenuStrip(Me) > > 'This visit all the items of All the ContextMenuStrip's in all > controls > 'or subcontrols of this form > Me.RecurseContextMenuStrip(Me) > > End Sub > > Sub RecurseMenuStrip(ByVal Control As Control) > > For Each ControlChild As Control In Control.Controls > If TypeOf ControlChild Is MenuStrip Then > Dim MenuStrip As MenuStrip = DirectCast(ControlChild, > MenuStrip) > Me.RecurseToolStripItems(MenuStrip.Items) > Else > Me.RecurseMenuStrip(ControlChild) > End If > Next ControlChild > > End Sub > > Sub RecurseContextMenuStrip(ByVal Control As Control) > > Dim FieldInfo As System.Reflection.FieldInfo = > Control.GetType.GetField("components", _ > > Reflection.BindingFlags.Instance Or _ > > Reflection.BindingFlags.NonPublic) > 'for context menu in control components > If FieldInfo IsNot Nothing Then > > Dim ControlComponents As System.ComponentModel.IContainer = > DirectCast(FieldInfo.GetValue(Control), > System.ComponentModel.IContainer) > If ControlComponents IsNot Nothing Then > For Each ControlChild As Control In > ControlComponents.Components > If TypeOf ControlChild Is ContextMenuStrip Then > Dim ContextMenuStrip As ContextMenuStrip = > DirectCast(ControlChild, ContextMenuStrip) > > Me.RecurseToolStripItems(ContextMenuStrip.Items) > Else > Me.RecurseContextMenuStrip(ControlChild) > End If > Next ControlChild > End If > End If > > 'for possible context menus in custom controls > For Each ControlChild As Control In Control.Controls > Me.RecurseContextMenuStrip(ControlChild) > Next ControlChild > > End Sub > > Sub RecurseToolStripItems(ByVal ToolStripItemCollection As > ToolStripItemCollection) > For Each ToolStripItem As ToolStripItem In > ToolStripItemCollection > > Me.DoSomethingWithToolStripItem(ToolStripItem) > > If TypeOf ToolStripItem Is ToolStripMenuItem Then > Dim ToolStripMenuItem As ToolStripMenuItem = > DirectCast(ToolStripItem, ToolStripMenuItem) > > Me.RecurseToolStripItems(ToolStripMenuItem.DropDownItems) > End If > Next ToolStripItem > End Sub > > Sub DoSomethingWithToolStripItem(ByVal ToolStripItem As > ToolStripItem) > MsgBox("I am on " & ToolStripItem.Text) > End Sub > > End Class > RobinS ha scritto:
> I'm going to ask a stupid question here. When you say context Is that's how microsoft call them :)> menus, you mean the menus that show up when you right-click on > something, right? > I hope it is. But I have written too many lines of codes to not be> So this code will go through all the menu items on a form, > whether it be in a menu strip at the top, a tool stip at the > top, or a context menu assigned to a control, right? > > Cooooool. absolutely sure this code written so hastily contains somewhere some bugs :)) Anyway this is the form in which I am going to use it. Since I may need to use it in several places of my programs it's just the case to have a reusable class. Here is a sample of use. Please let me know when discover errors ... Public Class Form1 'EXAMPLE OF USE OF THE "MENU RECURSOR" '===================================== 'if anyone uses this and finds bugs or improvements I'd love to know: pamelaflue***@libero.it Private WithEvents MenuRecursor As New MenuRecursor Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.MenuRecursor = New MenuRecursor End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click With Me.MenuRecursor 'This visit all the items of All the MenuStrip's in all controls 'or subcontrols (got first) of this form .RecurseMenuStrip(Me) 'This visit all the items of All the ContextMenuStrip's in all controls 'or subcontrols of this form .RecurseContextMenuStrip(Me) End With End Sub Sub HandleFoundToolStripMenuItem(ByVal ToolStripItem As ToolStripItem) Handles MenuRecursor.FoundToolStripMenuItem MsgBox("I am on " & ToolStripItem.Name) End Sub End Class Public Class MenuRecursor Public Event FoundToolStripMenuItem(ByVal ToolStripItem As ToolStripItem) Sub RecurseMenuStrip(ByVal Control As Control) For Each ControlChild As Control In Control.Controls If TypeOf ControlChild Is MenuStrip Then Dim MenuStrip As MenuStrip = DirectCast(ControlChild, MenuStrip) Me.RecurseToolStripItems(MenuStrip.Items) Else Me.RecurseMenuStrip(ControlChild) End If Next ControlChild End Sub Sub RecurseContextMenuStrip(ByVal Control As Control) Dim FieldInfo As System.Reflection.FieldInfo = Control.GetType.GetField("components", _ Reflection.BindingFlags.Instance Or _ Reflection.BindingFlags.NonPublic) 'for context menu in control components If FieldInfo IsNot Nothing Then Dim ControlComponents As System.ComponentModel.IContainer = DirectCast(FieldInfo.GetValue(Control), System.ComponentModel.IContainer) If ControlComponents IsNot Nothing Then For Each ControlChild As Control In ControlComponents.Components If TypeOf ControlChild Is ContextMenuStrip Then Dim ContextMenuStrip As ContextMenuStrip = DirectCast(ControlChild, ContextMenuStrip) Me.RecurseToolStripItems(ContextMenuStrip.Items) Else Me.RecurseContextMenuStrip(ControlChild) End If Next ControlChild End If End If 'for possible context menus in custom controls For Each ControlChild As Control In Control.Controls Me.RecurseContextMenuStrip(ControlChild) Next ControlChild End Sub Sub RecurseToolStripItems(ByVal ToolStripItemCollection As ToolStripItemCollection) For Each ToolStripItem As ToolStripItem In ToolStripItemCollection RaiseEvent FoundToolStripMenuItem(ToolStripItem) If TypeOf ToolStripItem Is ToolStripMenuItem Then Dim ToolStripMenuItem As ToolStripMenuItem = DirectCast(ToolStripItem, ToolStripMenuItem) Me.RecurseToolStripItems(ToolStripMenuItem.DropDownItems) End If Next ToolStripItem End Sub End Class I tried out the menu strip stuff, and it worked like a dream.
You're brilliant. Robin S <pamelaflue***@libero.it> wrote in message Show quoteHide quote news:1162951929.882270.233340@f16g2000cwb.googlegroups.com... > > RobinS ha scritto: > >> I'm going to ask a stupid question here. When you say context >> menus, you mean the menus that show up when you right-click on >> something, right? > > Is that's how microsoft call them :) > >> >> So this code will go through all the menu items on a form, >> whether it be in a menu strip at the top, a tool stip at the >> top, or a context menu assigned to a control, right? >> >> Cooooool. > > I hope it is. But I have written too many lines of codes to not be > absolutely sure this code written so hastily contains somewhere some > bugs :)) > > Anyway this is the form in which I am going to use it. Since I may need > to use it in several places of my programs it's just the case to have a > reusable class. > > Here is a sample of use. Please let me know when discover errors ... > > > Public Class Form1 > > > 'EXAMPLE OF USE OF THE "MENU RECURSOR" > '===================================== > > 'if anyone uses this and finds bugs or improvements I'd love to > know: pamelaflue***@libero.it > > Private WithEvents MenuRecursor As New MenuRecursor > > Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As > System.EventArgs) Handles MyBase.Load > Me.MenuRecursor = New MenuRecursor > End Sub > > Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As > System.EventArgs) Handles Button1.Click > > With Me.MenuRecursor > > 'This visit all the items of All the MenuStrip's in all > controls > 'or subcontrols (got first) of this form > > .RecurseMenuStrip(Me) > > 'This visit all the items of All the ContextMenuStrip's in > all controls > 'or subcontrols of this form > > .RecurseContextMenuStrip(Me) > > End With > > End Sub > > Sub HandleFoundToolStripMenuItem(ByVal ToolStripItem As > ToolStripItem) Handles MenuRecursor.FoundToolStripMenuItem > MsgBox("I am on " & ToolStripItem.Name) > End Sub > > End Class > > > > Public Class MenuRecursor > > Public Event FoundToolStripMenuItem(ByVal ToolStripItem As > ToolStripItem) > > Sub RecurseMenuStrip(ByVal Control As Control) > > For Each ControlChild As Control In Control.Controls > If TypeOf ControlChild Is MenuStrip Then > Dim MenuStrip As MenuStrip = DirectCast(ControlChild, > MenuStrip) > Me.RecurseToolStripItems(MenuStrip.Items) > Else > Me.RecurseMenuStrip(ControlChild) > End If > Next ControlChild > > End Sub > > Sub RecurseContextMenuStrip(ByVal Control As Control) > > Dim FieldInfo As System.Reflection.FieldInfo = > Control.GetType.GetField("components", _ > > Reflection.BindingFlags.Instance Or _ > > Reflection.BindingFlags.NonPublic) > 'for context menu in control components > If FieldInfo IsNot Nothing Then > > Dim ControlComponents As System.ComponentModel.IContainer = > DirectCast(FieldInfo.GetValue(Control), > System.ComponentModel.IContainer) > If ControlComponents IsNot Nothing Then > For Each ControlChild As Control In > ControlComponents.Components > If TypeOf ControlChild Is ContextMenuStrip Then > Dim ContextMenuStrip As ContextMenuStrip = > DirectCast(ControlChild, ContextMenuStrip) > > Me.RecurseToolStripItems(ContextMenuStrip.Items) > Else > Me.RecurseContextMenuStrip(ControlChild) > End If > Next ControlChild > End If > End If > > 'for possible context menus in custom controls > For Each ControlChild As Control In Control.Controls > Me.RecurseContextMenuStrip(ControlChild) > Next ControlChild > > End Sub > > Sub RecurseToolStripItems(ByVal ToolStripItemCollection As > ToolStripItemCollection) > For Each ToolStripItem As ToolStripItem In > ToolStripItemCollection > > RaiseEvent FoundToolStripMenuItem(ToolStripItem) > > If TypeOf ToolStripItem Is ToolStripMenuItem Then > Dim ToolStripMenuItem As ToolStripMenuItem = > DirectCast(ToolStripItem, ToolStripMenuItem) > > Me.RecurseToolStripItems(ToolStripMenuItem.DropDownItems) > End If > Next ToolStripItem > End Sub > > End Class > RobinS ha scritto:
> I tried out the menu strip stuff, and it worked like a dream. Here is a slightly better version, working both with FORMS and CONTROLSGood. (forms are controls anyway). Replaced events with delegates because more flexible. COrrected the tooltip component bug ... When attaching to click (or similar) event of items it's more convenient to use the itemclicked event so that we can avoid recursing on items .... Let me know in case of bugs '===================================================== Public Delegate Sub ToolStripMenuItemSub(ByVal ToolStripItem As ToolStripItem) Public Delegate Sub ContextMenuStripSub(ByVal ContextMenuStrip As ContextMenuStrip) Public Delegate Sub MenuStripSub(ByVal MenuStrip As MenuStrip) Public Class MenuRecursor Public ToolStripMenuItemSub As ToolStripMenuItemSub Public ContextMenuStripSub As ContextMenuStripSub Public MenuStripSub As MenuStripSub Sub RecurseMenuStrip(ByVal Control As Control) For Each ControlChild As Control In Control.Controls If TypeOf ControlChild Is MenuStrip Then 'Invoke -------- Dim MenuStrip As MenuStrip = DirectCast(ControlChild, MenuStrip) If Me.MenuStripSub IsNot Nothing Then Me.MenuStripSub(MenuStrip) '--------------- Me.RecurseToolStripItems(MenuStrip.Items) Else Me.RecurseMenuStrip(ControlChild) End If Next ControlChild End Sub Sub RecurseContextMenuStrip(ByVal FormOrControl As Control) Dim FieldInfo As System.Reflection.FieldInfo = FormOrControl.GetType.GetField("components", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic) 'for context menu in control components If FieldInfo IsNot Nothing Then Dim ControlComponents As System.ComponentModel.IContainer = DirectCast(FieldInfo.GetValue(FormOrControl), System.ComponentModel.IContainer) If ControlComponents IsNot Nothing Then For Each o As Object In ControlComponents.Components If TypeOf o Is ContextMenuStrip Then 'Invoke -------- Dim ContextMenuStrip As ContextMenuStrip = DirectCast(o, ContextMenuStrip) If Me.ContextMenuStripSub IsNot Nothing Then Me.ContextMenuStripSub(ContextMenuStrip) '--------------- Me.RecurseToolStripItems(ContextMenuStrip.Items) Else If TypeOf o Is Control Then Me.RecurseContextMenuStrip(DirectCast(o, Control)) End If End If Next o End If End If 'for possible context menus in custom controls For Each ControlChild As Control In FormOrControl.Controls Me.RecurseContextMenuStrip(ControlChild) Next ControlChild End Sub Sub RecurseToolStripItems(ByVal ToolStripItemCollection As ToolStripItemCollection) For Each ToolStripItem As ToolStripItem In ToolStripItemCollection 'Invoke -------- If Me.ToolStripMenuItemSub IsNot Nothing Then Me.ToolStripMenuItemSub(ToolStripItem) '--------------- If TypeOf ToolStripItem Is ToolStripMenuItem Then Dim ToolStripMenuItem As ToolStripMenuItem = DirectCast(ToolStripItem, ToolStripMenuItem) Me.RecurseToolStripItems(ToolStripMenuItem.DropDownItems) End If Next ToolStripItem End Sub End Class Cool; I'll check it out this weekend. Thanks for
sharing this, Pamela! Robin S. <pamelaflue***@libero.it> wrote in message Show quoteHide quote news:1163158510.880321.39310@m7g2000cwm.googlegroups.com... > > RobinS ha scritto: > >> I tried out the menu strip stuff, and it worked like a dream. > Good. > > > Here is a slightly better version, working both with FORMS and CONTROLS > (forms are controls anyway). Replaced events with delegates because > more flexible. COrrected the tooltip component bug ... > > When attaching to click (or similar) event of items it's more > convenient to use the itemclicked event so that we can avoid recursing > on items .... > > Let me know in case of bugs > > '===================================================== > > Public Delegate Sub ToolStripMenuItemSub(ByVal ToolStripItem As > ToolStripItem) > Public Delegate Sub ContextMenuStripSub(ByVal ContextMenuStrip As > ContextMenuStrip) > Public Delegate Sub MenuStripSub(ByVal MenuStrip As MenuStrip) > > Public Class MenuRecursor > > Public ToolStripMenuItemSub As ToolStripMenuItemSub > Public ContextMenuStripSub As ContextMenuStripSub > Public MenuStripSub As MenuStripSub > > Sub RecurseMenuStrip(ByVal Control As Control) > > For Each ControlChild As Control In Control.Controls > > If TypeOf ControlChild Is MenuStrip Then > > 'Invoke -------- > Dim MenuStrip As MenuStrip = DirectCast(ControlChild, > MenuStrip) > If Me.MenuStripSub IsNot Nothing Then > Me.MenuStripSub(MenuStrip) > '--------------- > > Me.RecurseToolStripItems(MenuStrip.Items) > Else > Me.RecurseMenuStrip(ControlChild) > End If > > Next ControlChild > > End Sub > > Sub RecurseContextMenuStrip(ByVal FormOrControl As Control) > > Dim FieldInfo As System.Reflection.FieldInfo = > FormOrControl.GetType.GetField("components", > Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic) > > 'for context menu in control components > If FieldInfo IsNot Nothing Then > > Dim ControlComponents As System.ComponentModel.IContainer = > DirectCast(FieldInfo.GetValue(FormOrControl), > System.ComponentModel.IContainer) > If ControlComponents IsNot Nothing Then > > For Each o As Object In ControlComponents.Components > > If TypeOf o Is ContextMenuStrip Then > > 'Invoke -------- > Dim ContextMenuStrip As ContextMenuStrip = > DirectCast(o, ContextMenuStrip) > If Me.ContextMenuStripSub IsNot Nothing Then > Me.ContextMenuStripSub(ContextMenuStrip) > '--------------- > > > Me.RecurseToolStripItems(ContextMenuStrip.Items) > > Else > If TypeOf o Is Control Then > Me.RecurseContextMenuStrip(DirectCast(o, > Control)) > End If > End If > > Next o > End If > End If > > 'for possible context menus in custom controls > For Each ControlChild As Control In FormOrControl.Controls > Me.RecurseContextMenuStrip(ControlChild) > Next ControlChild > > End Sub > > Sub RecurseToolStripItems(ByVal ToolStripItemCollection As > ToolStripItemCollection) > > For Each ToolStripItem As ToolStripItem In > ToolStripItemCollection > > 'Invoke -------- > If Me.ToolStripMenuItemSub IsNot Nothing Then > Me.ToolStripMenuItemSub(ToolStripItem) > '--------------- > > If TypeOf ToolStripItem Is ToolStripMenuItem Then > Dim ToolStripMenuItem As ToolStripMenuItem = > DirectCast(ToolStripItem, ToolStripMenuItem) > > Me.RecurseToolStripItems(ToolStripMenuItem.DropDownItems) > End If > > Next ToolStripItem > > End Sub > > End Class > I managed to add MouseEnter and MouseLeave event
handlers to all of my menu options using your code. Can't you just do this? Private Sub AddMenuStripEventHandlers(ByVal msMenuStrip As MenuStrip) RecurseItems(Me.MenuStrip.Items) End Sub Sub RecurseItems(ByVal ToolStripItemCollection As ToolStripItemCollection) Try For Each ToolStripMenuItemChild As ToolStripMenuItem _ In ToolStripItemCollection 'Debug.Print("I am on " & ToolStripMenuItemChild.Text) If ToolStripMenuItemChild.Tag IsNot Nothing Then AddHandler ToolStripMenuItemChild.MouseEnter, _ AddressOf MenuItem_MouseEnter AddHandler ToolStripMenuItemChild.MouseLeave, _ AddressOf MenuItem_MouseLeave End If RecurseItems(ToolStripMenuItemChild.DropDownItems) Next ToolStripMenuItemChild Catch ex As InvalidCastException 'ignore it; you'll get this for the separator lines End Try End Sub The only sticky wicket is the ToolStripMenuItemChild not being a ToolStripMenuItem. If it's not, do you want a MouseEnter event for it anyway? Also, I'm using the Tag in the above example, because my MouseEnter event sets a status bar at the bottom of the screen to whatever the Tag is, so I don't need an event if there's no tag. Robin S <pamelaflue***@libero.it> wrote in message news:1162947344.099182.153800@m73g2000cwd.googlegroups.com... I am working on it. It's subtle because the contextmenu are incomponents not in controls. So recursion on the form seems tricky because "components" is private (aarg!) I would not suggest to use Try catch for that. It's ugly. I will try to work out a general solution in the next minutes which consider separators too. Warn me if there are other things that should be taken cared of ... -P RobinS ha scritto: Show quoteHide quote > That's cool! I had to put in a Try/Catch to pick up > the InvalidCastException error, because I have > separator lines in my toolbars, and they are not > ToolStripMenuItems. I'm going to send this to that > other guy who was looking for this. > > So did you fix your problem with adding an event handler > for Mouse Enter? > > Robin S > --------------------------------- > > <pamelaflue***@libero.it> wrote in message > news:1162941209.095687.108050@m73g2000cwd.googlegroups.com... > > RobinS ha scritto: > > > The main container is a MenuStrip. Inside the menu strip, there are > > ToolStripMenuItems. This gives you access to the items you can > > see on the menu strip. From there, you can access DropDownItems > > to get to the options that you see when you drop down. I haven't > > figured out how to get to the options that show to the right for > > each of the dropdown items yet. This is as far as I got: > > > > 'For each option you can see on the menu strip > > For each tsItem As ToolStripMenuItem in msMenuStrip.Items > > If tsItem.DropDownItems.Count > 0 then > > 'that entry has a dropdown > > For i as Integer = 0 to item.DropDownItems.Count - 1 > > Dim ddItem as ToolStripItm > > ddItem = item.DropDownItems(i) > > 'Now you can access ddItem, but I couldn't figure out > > ' how to get from here to the next level of dropdowns. > > Next > > End If > > Next > > > > You're not dumb. Nobody else answered the other post about > > this, and I searched google and microsoft and couldn't find > > anything telling how to enumerate through all of the levels of > > a menustrip/toolstrip. > > > > Let me know if you figure it out; I'm waiting with bated breath. > > > that would seem easy. Is this what you mean ? > > > Public Class Form1 > > Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As > System.EventArgs) Handles Button1.Click > > 'Visit All Context MenuStrip > RecurseItems(Me.ContextMenuStrip1.Items) > > End Sub > > Sub RecurseItems(ByVal ToolStripItemCollection As > ToolStripItemCollection) > For Each ToolStripMenuItemChild As ToolStripMenuItem In > ToolStripItemCollection > Me.DoSomethingWithToolStripMenuItem(ToolStripMenuItemChild) > RecurseItems(ToolStripMenuItemChild.DropDownItems) > Next ToolStripMenuItemChild > End Sub > > Sub DoSomethingWithToolStripMenuItem(ByVal ToolStripMenuItemChild > As ToolStripMenuItem) > MsgBox("I am on " & ToolStripMenuItemChild.Text) > End Sub > > End Class > > > > > > > > Robin S. > > irish underscore songbird at comcast dot net > > ------------------------------------------------------------------------------- > > <pamelaflue***@libero.it> wrote in message > > news:1162906283.550715.305840@e3g2000cwe.googlegroups.com... > > > > RobinS ÀÛ¼º: > > > > > If you search this form for my earlier post titled > > > "Re: tootip or microhelp for menu items", I posted > > > code that will add event handlers for one level down. > > > I couldn't figure out how to do it two or more > > > levels down. > > > > Hi Robin, > > > > thanks. For the levels there is no problem: as you can see, I am > > already doing recursion. My problem is to identify the container which > > contains the toolstripitems. It does not seem to be "controls". > > > > Are you suggesting I have to first iterate on toolstrip menu and then > > make recursion on toolstrip item? I must be dumb: I cannot see how to > > do this apparently simple thing... :( > > > > /P > > > > > > > > > > Good luck. > > > Robin S. > > > > > > > > > <pamelaflue***@libero.it> wrote in message > > > news:1162849338.134785.23570@m73g2000cwd.googlegroups.com... > > > > Hello. I have written the following code (this code is on a > > > > control): > > > > > > > > Sub InitSomething() > > > > mSet(me.FindForm) > > > > End Sub > > > > > > > > Sub mSet(ByVal f As Control) > > > > For Each t As Control In f.Controls > > > > If TypeOf t Is ToolStripMenuItem Then > > > > AddHandler t.MouseEnter, AddressOf Me.SetSemaforoMenu > > > > End If > > > > mSet(t) > > > > Next t > > > > End Sub > > > > > > > > because I wanted to attach an handler to the MouseEnter event of all > > > > the > > > > ToolStripMenuItems which are on the form which contains this > > > > control. > > > > > > > > But this gives error because it says ToolStripMenuItem is not a > > > > control. > > > > Well how do I iterate on my ToolStripMenuItems. Is there a container > > > > or > > > > what ? > > > > > > > > -P > > > >
MDI gets FormClosing but non-Child forms also open do not.
Query based on user input C# help!!! Challenge? [De-]Serialise a class derived from DataTable. Getting XML Version Multithread Design Question Memory by user Sorting a datagrigview Getting an application to be on top of other applications Treeview - relative position |
|||||||||||||||||||||||