65.9K
CodeProject 正在变化。 阅读更多。
Home

动态创建MenuStrip - VB.NET

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.96/5 (15投票s)

2007年6月17日

CPOL

1分钟阅读

viewsIcon

240527

downloadIcon

9787

从数据库动态实现MenuStrip,菜单名称和顺序将通过后端控制。

引言

我遇到了一个问题,需要创建一个根据用户权限驱动的应用程序。我想到通过后端实现菜单驱动。所有菜单名称和点击子菜单时要打开的窗体(窗体名)都来自表。为了实现菜单,我使用了 VB.NET 中的 MenuStrip

示例代码

Using the Code

它在窗体加载时执行,并填充所有菜单标题。所有数据都来自后端,没有任何硬编码。我附上了两个表 MENUMASTER ACCESS 的结构如下。

下面的代码将有一个变量,例如 iUserAccessMode,它反过来告诉我们用户访问级别(查看附件的 Excel 表格,并查看 Excel 表格中的 Access 选项卡)。菜单将根据用户访问级别加载。

 Private Sub MDIParent1_Load(ByVal sender As Object,
        ByVal e As System.EventArgs) Handles Me.Load
        'On Error GoTo ErrHandler
 'Create a Connection class, that has the full features of working with Backend.
 'See article for Connection class :  Connection_Class.asp
 
        Dim Conn As New Conn1
        Dim mnRd As SqlClient.SqlDataReader
 'It helps in populating the MENUs according to user rights. From the Table "Access"
        iUserAccessMode = GlobalValues.lblUsrAccess.Text
        sQry = ""
        sQry = "Select MenuText from MenuMaster Where MainMenuID = 0" & _
               " And MenuID in (Select MenuID from Access Where AccessId =
                " & CInt(iUserAccessMode) & ")" & _
                " And isActive = 1"
        mnRd = Conn.ReaderData(sQry)
        
 If mnRd.HasRows Then
            mnMenu = New MenuStrip
            While mnRd.Read
                mnMenu.Items.Add(mnRd(0).ToString, Nothing, New System.EventHandler(
                    AddressOf MainMenu_OnClick))
                Me.Controls.Add(mnMenu)
            End While
        End If
        
 mnRd.Close()
    End Sub

此函数在创建父菜单时创建子菜单。

Private Sub MainMenu_OnClick(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim cms As New ContextMenuStrip()
        Dim sMenu() As String
        Dim Conn As New Conn1
        Dim sMenuRD As SqlClient.SqlDataReader
        sQry = ""
        sQry = "Select MenuID from MenuMaster Where MenuText = '" & sender.ToString & "'"
        sMenuRD = Conn.ReaderData(sQry)
        Dim parentMenuID As Integer
        If sMenuRD.HasRows Then
            sMenuRD.Read()
            parentMenuID = sMenuRD("MenuID")
        End If
        sMenuRD.Close()
        sQry = ""
        sQry = "Select MenuText from MenuMaster Where MainMenuID =
               '" & parentMenuID & "'" & _
               " And isActive = 1" & _
               " And MenuID in (
                   Select MenuID from Access Where AccessId =
                   " & CInt(iUserAccessMode) & ")" & _
               " Order BY MenuOrder"
        sMenuRD = Conn.ReaderData(sQry)
        ReDim Preserve sMenu(0)
        Dim i As Integer
        If sMenuRD.HasRows Then
            ReDim Preserve sMenu(0)
            i = 0
            While sMenuRD.Read()
                ReDim Preserve sMenu(i)
                sMenu(i) = sMenuRD("MenuText")
                i = i + 1
            End While
        End If
        sMenuRD.Close()
        For Each sMn As String In sMenu
            cms.Items.Add(sMn, Nothing,
                New System.EventHandler(AddressOf SelectedChildMenu_OnClick))
        Next
        Dim tsi As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
        tsi.DropDown = cms
    End Sub

此函数在每个菜单项的点击事件中执行,要打开的窗体(FormName)也在事件执行时从后端表 "MENUMASTER" 中获取。

    Private Sub SelectedChildMenu_OnClick(ByVal sender As Object,
        ByVal e As System.EventArgs)
        Dim Conn As New Conn1
        Dim sMenuRD As SqlClient.SqlDataReader
        Dim frmName As String = ""
        Dim frm As New Form
        sQry = ""
        sQry = "Select FormName from MenuMaster Where MenuText = '" &
            sender.ToString & "'"
        sMenuRD = Conn.ReaderData(sQry)
        If sMenuRD.HasRows Then
            sMenuRD.Read()
            frmName = sMenuRD(0).ToString
            DynamicallyLoadedObject(frmName).Show(Me)
        Else
            MsgBox("Under Construction", MsgBoxStyle.Exclamation, "Technical Error")
        End If
        sMenuRD.Close()
    End Sub

关注点

我遇到了将从 SQL 获取的 string 类型的窗体名转换为 FORM 对象的问题。此函数有助于将从 SQL 返回的 string 对象 formName 转换为 Form 类型的对象。

    Private Function DynamicallyLoadedObject(ByVal objectName As String,
        Optional ByVal args() As Object = Nothing) As Form
        Dim returnObj As Object = Nothing
        Dim Type As Type = Assembly.GetExecutingAssembly().GetType(
            "[YOUR PROJECT NAME]." & objectName)
        If Type IsNot Nothing Then
            returnObj = Activator.CreateInstance(Type, args)
        End If
        Return returnObj
    End Function

历史

  • 2007 年 6 月 17 日:初始发布
© . All rights reserved.