3
\$\begingroup\$

I have multiple menus that will change languages in one Sub that will handle multiple events of the menus click, It is working for me right now, I'm just wondering if there is better way to do it... I'm using the menus name to call the process for each menus.

 Private Shared Sub CheckMenuItem(ByVal mnu As ToolStripMenuItem, ByVal checked_item As ToolStripMenuItem)
 For Each menu_item As ToolStripMenuItem In mnu.DropDownItems.OfType(Of ToolStripMenuItem)()
 menu_item.Checked = (menu_item Is checked_item)
 Next
End Sub
 Private Sub mnuEnglish_Click(sender As System.Object, e As EventArgs) _
 Handles mnuEnglish.Click, mnuFrench.Click, mnuDutch.Click, _ 
 mnuGerman.Click,mnuCroatian.Click, mnuCzech.Click, mnuHungarian.Click, _
 mnuIndonesian.Click, mnuItalian.Click, mnuPolish.Click, mnuSlovak.Click, _
 mnuSpanish.Click, mnuSwedish.Click, mnuTurkish.Click, mnuVietnamese.Click
 Dim item As ToolStripMenuItem = DirectCast(sender, ToolStripMenuItem)
 CheckMenuItem(mnuLanguage, item)
 Select Case item.Name
 Case "mnuEnglish"
 MsgBox("english")
 Case "mnuFrench"
 MsgBox("French")
 Case Else
 MsgBox("Other Languages")
 End Select
 End Sub
Mathieu Guindon
75.5k18 gold badges194 silver badges467 bronze badges
asked Mar 21, 2014 at 16:42
\$\endgroup\$
0

4 Answers 4

5
\$\begingroup\$

See this Stack Overflow answer, where Cody Gray explains the syntax for the two ways of registering event handlers in :

The first involves the use of the Handles keyword, which you append to the end of the event handler method's definition. [...] The second involves the explicit use of the AddHandler statement, just like += in C#.

This means instead of statically declaring all the handled events with a Handles keyword, you write code to add the handlers yourself:

Public Sub New()
 InitializeComponents()
 AddHandler mnuEnglish.Click, AdressOf mnuEnglish_Click
 AddHandler mnuFrench.Click, AdressOf mnuEnglish_Click
 '...
End Sub

Or even better, loop through the menu items in that menu object, and assing all Click events the AdressOf mnuEnglish_Click, so you won't have the opportunity to forget updating that piece of code when you add a new language / menu item in the designer:

Public Sub New()
 InitializeComponents()
 ForEach item As ToolStripMenuItem In mnu.DropDownItems.OfType(Of ToolStripMenuItem)()
 AddHandler item.Click, AdressOf mnuEnglish_Click
 Next
End Sub
answered Apr 13, 2014 at 0:59
\$\endgroup\$
2
  • 1
    \$\begingroup\$ thanks to this, works great, still you need to check for type for ToolStripSeparator...the code you provided will have an error if there is a separator in DropDownItems in menus \$\endgroup\$ Commented Apr 27, 2014 at 15:55
  • \$\begingroup\$ @mercenary interesting.. I would have thought item would be Nothing when it's a ToolStripSeparator, because of As ToolStripMenuItem - looks like you need to further filter the items with .OfType(Of ToolStripMenuItem)... I'll edit out the last part of my answer then ;) \$\endgroup\$ Commented Apr 27, 2014 at 19:31
3
\$\begingroup\$

The ToolStripItem contains a property called Tag which is used to store extra information about a menu item. This is where you could store information about the language. Then your event could be generalized by using the information in Tag.

mnuEnglish.Tag = "English" ' Instead of just a string, I would have a language class
mnuFrench.Tag = "French"
...
Private Sub mnuEnglish_Click(...
Dim item As ToolStripMenuItem = DirectCast(sender, ToolStripMenuItem)
 CheckMenuItem(mnuLanguage, item)
 MsgBox(item.Tag)
End Sub
Malachi
29k11 gold badges86 silver badges188 bronze badges
answered Mar 28, 2014 at 15:55
\$\endgroup\$
1
\$\begingroup\$

so silly of me, simple google solve my problem

For Each item As ToolStripMenuItem In mnuLanguage.DropDownItems.OfType(Of ToolStripMenuItem)()
 If item.Name IsNot "mnuEnglish" Then
 AddHandler item.Click, AddressOf mnuEnglish_Click
 End If
Next

of this converted to LINQ expression thanks to Resharper

For Each item As ToolStripMenuItem In From mnu_items In mnuLanguage.DropDownItems.OfType(Of ToolStripMenuItem)() Where mnu_items.Name IsNot "mnuEnglish"
 AddHandler item.Click, AddressOf mnuEnglish_Click
Next
answered Apr 27, 2014 at 16:55
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Could you explain what the difference between these is and how it improves things? It's not much of a review when it doesn't teach better practices. \$\endgroup\$ Commented Sep 29, 2015 at 19:35
1
\$\begingroup\$

Make sure you have only one handler for every event. If you use the "Handles" syntax at the end of the subroutine declaration for the click handler, that registers a handler.

For derived classes, if the base handler is defined with a "Handles" clause, it register a handler. If the overrides handler in the derived class is also defined with a "Handles" clause, it will register a second handler, and both will be triggered when the event is fired.

answered Oct 15, 2014 at 2:37
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.