分享
 
 
 

动态生成多级菜单

王朝other·作者佚名  2006-12-25
窄屏简体版  字體: |||超大  

以前,我是用数据表保存菜单项目及各个操作员的相应权限,并在vfp中编写了相应的程序来实现菜单、工具栏、Treeview 的生成。但由于vfp有一个叫宏替换的东东&,实现起来比较简单。

由于vb及.net的“对象”和“对象名称”是两种不同的数据类型,之间转换起来比较麻烦,以一直困扰了我很久了。

经过一段时间的努力,终于实现了上述的功能。

具体做法是:

我把系统中使用的各级菜单的信息保存在数据表中,把菜单的级次关系描述清楚(注意Bhparent字段)。

数据表的结构如下:

MenBh c 8 '菜单编号

MenText c 20 '菜单项

Bhparent c 8 '上级菜单编号

MenForm C 20 '需要执行的窗体名称

数据表中记录是:

MenBh: 0001 MenText: 文件 Bhparent: 无

MenBh: 0005 MenText: 打开 Bhparent: 0001

MenBh: 0006 MenText: 新建 Bhparent: 0001

MenBh: 0011 MenText: access数据库 Bhparent: 0006

MenBh: 0011 MenText: VFP的Dbf Bhparent: 0006

这样可以定义多个级次的菜单。

我自己定义了一个类BqUMenuItem,继承于MenuItem,主要是添加了一个tag属性,以使我在编写click事件时,可以方便地调用相关的窗口.

Public Class BqUMenuItem

Inherits System.Windows.Forms.MenuItem

#Region " Windows 窗体设计器生成的代码 "

Public Sub New()

MyBase.New()

'该调用是 Windows 窗体设计器所必需的。

InitializeComponent()

'在 InitializeComponent() 调用之后添加任何初始化

End Sub

'UserControl 重写 dispose 以清理组件列表。

Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

If disposing Then

If Not (components Is Nothing) Then

components.Dispose()

End If

End If

MyBase.Dispose(disposing)

End Sub

'Windows 窗体设计器所必需的

Private components As System.ComponentModel.IContainer

'注意: 以下过程是 Windows 窗体设计器所必需的

'可以使用 Windows 窗体设计器修改此过程。

'不要使用代码编辑器修改它。

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

components = New System.ComponentModel.Container

End Sub

#End Region

Dim lpToolsTip As String '帮助提示

Dim lpTag As Object '

Dim lpID As String '菜单ID

Dim lpAdd As Boolean = True '新增

Dim lpEdi As Boolean = True '修改

Dim lpDel As Boolean = True '删除

Dim lpPrn As Boolean = True '打印

Dim lpBow As Boolean = True '预览

Dim lpOut As Boolean = True '导出

Dim lpBhmode As String = " " '模块编号

Dim lpMcmode As String = " " '模块名称

Dim lpFrm As String = " " '模块名称

Public Property BqPAdd() As Boolean

Get

Return lpAdd

End Get

Set(ByVal Value As Boolean)

lpAdd = Value

End Set

End Property

Public Property BqPEdi() As Boolean

Get

Return lpEdi

End Get

Set(ByVal Value As Boolean)

lpEdi = Value

End Set

End Property

Public Property BqPDel() As Boolean

Get

Return lpDel

End Get

Set(ByVal Value As Boolean)

lpDel = Value

End Set

End Property

Public Property BqPPrn() As Boolean

Get

Return lpPrn

End Get

Set(ByVal Value As Boolean)

lpPrn = Value

End Set

End Property

Public Property BqPBow() As Boolean

Get

Return lpBow

End Get

Set(ByVal Value As Boolean)

lpBow = Value

End Set

End Property

Public Property BqPOut() As Boolean

Get

Return lpOut

End Get

Set(ByVal Value As Boolean)

lpOut = Value

End Set

End Property

Public Property BqPBhmode() As String

Get

Return lpBhmode

End Get

Set(ByVal Value As String)

lpBhmode = Value

End Set

End Property

Public Property BqPFrm() As String

Get

Return lpFrm

End Get

Set(ByVal Value As String)

lpFrm = Value

End Set

End Property

Public Property BqPMcmode() As String

Get

Return lpMcmode

End Get

Set(ByVal Value As String)

lpMcmode = Value

End Set

End Property

Public Property BqPTag()

Get

Return lpTag

End Get

Set(ByVal Value)

lpTag = Value

End Set

End Property

Public Property BqPID() As String

Get

Return lpID

End Get

Set(ByVal Value As String)

lpID = Value

End Set

End Property

Public Property BqPToolstip() As String

Get

Return lpToolsTip

End Get

Set(ByVal Value As String)

lpToolsTip = Value

End Set

End Property

End Class

最后,用以下代码来生成菜单

Public MenuNew As New System.Windows.Forms.MainMenu

Public Function BqMmode(ByVal ltb As DataTable)

Try

Dim lDt As New System.Data.DataSet

Dim tb As New DataTable

tb = ltb.Copy '不能直接用lTb这个表,因为,重新添加节点时,会提示“表已经在另一个数据集DataSet中

lDt.Clear()

lDt.Relations.Clear()

lDt.EnforceConstraints = False

lDt.Tables.Add(tb)

Dim dr1 As New DataRelation("self", tb.Columns("BHmode"), tb.Columns("BHparent"))

lDt.Relations.Add(dr1)

Dim r1 As DataRow

For Each r1 In lDt.Tables(0).Rows

If r1.IsNull("BHparent") Then 'Or r1.Item("BHparent") = "0000" Then

mMenuAdd(r1, Nothing)

End If

Next

Catch ex As Exception

End Try

End Function

Private Sub mMenuAdd(ByVal r As DataRow, ByVal item As System.Windows.Forms.MenuItem)

Try

Dim lmBh As String, lmPa As String, lmFrm As String, lmKey As String

Dim lmMc As String, lmBz As String, lmAt As String

Dim lrSY As Boolean

Dim lrAdd As Boolean, lrEdi As Boolean, lrDel As Boolean

Dim lrPrn As Boolean, lrBow As Boolean, lrOut As Boolean

Dim lmc As String, s As String

Dim lk As System.Windows.Forms.Shortcut = Windows.Forms.Shortcut.None

With r

lmBh = "" & .Item("BHmode") '模块编号

lmPa = "" & .Item("BHparent") '上级模块编号

lmFrm = "" & .Item("FRMNAME") '表单名称

lmKey = "" & .Item("ModeKey") '快捷键,以下设置与菜单相关

lmAt = Trim("" & .Item("ModeAlt")) '快速键

lmMc = Trim("" & .Item("MCmode")) '模块名称,如果名称为-号,表示分隔符

lmBz = "" & .Item("MeM") '备注内容

lrSY = .Item("MarKsy") '设置各个菜单的enabled属性

lrAdd = .Item("blnAdd") '读出有关的权限

lrEdi = .Item("blnEdi")

lrDel = .Item("blnDel")

lrPrn = .Item("blnPrn")

lrBow = .Item("blnBow")

lrOut = .Item("blnOut")

End With

'关于快捷键的使用,要写一个转换程序,并使用Shortcut属性来设置

lmc = lmMc

If Microsoft.VisualBasic.Left(lmMc, 1) = "-" Then '在菜单名称中,左边第一个字符为 - ,则表示分隔符

lmc = "-"

Else '都把快速键加在左边

'根据有无快速键,生成左边字符

s = IIf(lmAt = "", Space(3), "(&" & Microsoft.VisualBasic.Left(lmAt, 1) & ")")

If Trim(lmPa) = "" Then '没有父级,表示一级菜单

lmc = Trim(s + lmc) '则左边加上快速键,再去除空格

Else

lmc = s + " " + lmc

'如果lmc不足15位(, 则在后面补空格)

lmc = IIf(Len(Trim(lmc)) < 18, lmc + Space(18 - Len(Trim(lmc))), lmc)

lk = IIf(Len(Trim(lmKey)) = 0 Or IsDBNull(lmKey), lk, MMgetShort(lmKey)) '根据表中的快捷键,得到快捷键对象

End If

End If

Dim mi As New bqbass.BqUMenuItem '自定义类,继承于MenuItem,添加了部分属性,见下

With mi 't自定义的菜单类,分别设置有以下表示权限的属性

.BqPAdd = lrAdd '添加数据

.BqPEdi = lrEdi '修改数据

.BqPDel = lrDel '删除数据

.BqPPrn = lrPrn '打印数据

.BqPBow = lrBow '预览数据

.BqPOut = lrOut '数据输出

.BqPBhmode = lmBh '模块编号

.BqPFrm = lmFrm '表单名称

.BqPMcmode = lmMc '模块名称

.BqPToolstip = lmBz '提示信息

.Text = lmc

.Shortcut = lk '根据表中的快捷键,得到快捷键对象

.ShowShortcut = True

End With

If item Is Nothing Then

MenuNew.MenuItems.Add(mi)

Else

item.MenuItems.Add(mi)

End If

mi.Enabled = lrSY '设置各菜单的权限

AddHandler mi.Click, AddressOf mMenuClick '定义各个菜单的click事件

AddHandler mi.Select, AddressOf mMenuBarMouse '添加状态栏说明

AddHandler mi.Popup, AddressOf mMenuBarMouse '添加状态栏说明

Dim r2 As DataRow

For Each r2 In r.GetChildRows("self")

mMenuAdd(r2, mi)

Next

Catch ex As Exception

End Try

End Sub

'我自己定义的 选择菜单后的操作,在状态栏上显示

Public Overridable Sub mMenuClick(ByVal sender As System.Object, ByVal e As System.EventArgs)

End Sub '外部使用

Private Sub mMenuBarMouse(ByVal sender As System.Object, ByVal e As System.EventArgs)

Me.BqBar2Cz("" & sender.BqPToolstip)

End Sub

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有