VB.NETBuild Menus at Run Time
Listing 1. Building menus at run time allows you to combine standard menu options with ones that derive directly from available assemblies. You can identify appropriate types by their base class or by attributes, and you can use other attributes to specify captions and the location of new options. ![]() Protected Overridable Sub BuildMenuFromAssembly() Dim assemblies As Reflection.Assembly() Dim types As System.Type() Dim baseMenu As Windows.Forms.Menu Dim deleg As System.Delegate Dim mnu As Windows.Forms.MenuItem If mnuMain Is Nothing Then Throw New _ System.ApplicationException( _ "Internal error - mnuMain is nothing") Else assemblies = Me.GetAssemblies For Each assem As Reflection.Assembly In _ assemblies If Array.IndexOf(ignoreAssemblies, _ assem.GetName.Name) < 0 AndAlso _ Not assem.GetName.Name.StartsWith( _ "System") Then types = assem.GetTypes For Each type As System.Type In _ types If IsValidChildForm(type) Then baseMenu = _ Me.GetBaseMenu(type) mnu = New MenuItemWithType( _ Me.GetCaption(type), _ AddressOf _ mnuDynamicItem_Click, _ type) baseMenu.MenuItems.Add _ (mnu) End If Next End If Next End If End Sub Protected Overridable Function GetAssemblies() _ As Reflection.Assembly() Return Threading.Thread.CurrentThread. _ GetDomain.GetAssemblies End Function Private Function IsValidChildForm(ByVal type As _ System.Type) As Boolean Dim ret As Boolean If Utility.GetCustomTypeAttribute( _ type, "DynamicSupport.ExcludeFromMenus" &_ "Attribute") Is Nothing Then If type.IsSubclassOf(GetType( _ DynamicSupport.BaseEditForm)) Then Return True ElseIf Not type.GetInterface( _ "DynamicSupport.IProcess") Is Nothing _ Then Return True ElseIf Not _ Utility.GetCustomTypeAttribute( _ type, "DynamicSupport." &_ "IncludeInMenuAttribute") Is Nothing _ Then Return True End If End If End Function Protected Function GetBaseMenu(ByVal type As _ System.Type) As Windows.Forms.Menu Dim obj As Object Dim caption As String Dim rescaption As String obj = Utility.GetCustomTypeAttribute(type, _ "DynamicSupport.BaseMenuAttribute") If TypeOf obj Is BaseMenuAttribute Then caption = CType(obj, _ BaseMenuAttribute).BaseMenu rescaption = _ GetResManager(type).GetString(caption) If (Not rescaption Is Nothing) AndAlso _ (rescaption.Trim.Length > 0) Then caption = rescaption End If Return GetBaseMenu(caption) Else Return GetDefaultMenu() End If End Function Protected Overridable Function GetDefaultMenu() _ As Windows.Forms.MenuItem Return GetBaseMenu("Action") End Function Private Function GetBaseMenu(ByVal caption As _ String) As Windows.Forms.MenuItem For Each MenuItem As Windows.Forms.MenuItem _ In Me.mnuMain.MenuItems If MenuItem.Text = caption Then Return MenuItem End If Next ' If we get here, it doesn't exist yet Return Me.mnuMain.MenuItems.Add(caption) End Function |