admin 管理员组

文章数量: 1086019


2024年3月27日发(作者:特斯拉事件最近进展)

维普资讯

1设计思想 

2实现方式 

VB的TreeView控件正好适合上述菜单结构的实现,本 

般的应用系统都有一个主画面,用户由该主画面 

文的控件就是由TreeView控件及lmAgeI血控件组合而成 

进人各个子系统及模块,这便需要菜单的导引,就像 

对于前面设计的Menu表有多种实现方式,例如采用 

windows的资源管理器一样.一层一层地打开文件夹.最 

递归法透层加入菜单项,但控制复杂、可能造成死循环、 

后看到各个文件。另外考虑应用系统扩展性(如增加模 

运行时占用系统资源严重。所以本文采用了一种更为简单 

块)及权限控制的要求,菜单必须是活的(如菜单结构从 

数据库中获得)。 

的方式,具体是按M锄u—ID升序排列将菜单表所有记录 

取出,然后逐个将菜单项加人TreeView控件。由于最高 

表1 

字段序号 字段英文名 字段中文名 字段类型 允许null 主键字段 字段说明 

每两位代亵1级。量多支持5圾。下级菜单鞠 

1 

Menu_ID 菜单编号 

Char(10) 否 是 

号的前几位即是上级幕单缩号。量膏一级菜 

单编号为霉长度字串

每级的两位铺码中第 

位为字母A—Z,第二位为披字O-9.每氧 

量多包耆260个菜单项。 

2 Mel3 Name 菜单名称 Char(30) 否 对量厩屡的粟单硬记曩模块名稚。其他菜单 

璃记曩子蕞统或模块组的名蒋。 

3 Menu

ModulelD 模块编号 Char(30) 否 

对量赢屡的幂单项记嚣蕞蟪墒号。其他菜簟 

项为,长度字审

。 

关键的核心是一个具有树状层级结构的菜单,本文 

级菜单项的Menu—ID为零长度子串,该项必然排在第 

以VB的TreeView控件为基础.开发出了满足上述要求 

条,父菜单项也会排在子菜单项的前面,所以产生菜单 

的实用菜单控件。子系统及模块的层次关系由数据库中 

结构时肯定是最先增加根节点.然后增加第一个一级节 

的一个表来描述,具体的表结构如下 

点.再增加第一个属于该节点的二级节点.直至最底层的 

其实Menu表也可以设计成其他结构,例如以菜单编 

模块。选正好复合TmeView控件上级节点必须存在才能 

号及上级菜单编号两个宇段为主键,这种表结构虽然支 

增加下级节点的特点。 

持任意级数的菜单.但需要维护两个字腔的关系容易出 

具体设计是该控件包括一个方法S ho w Me n i1 

错(例如两个菜单项的编号互为父子关系.造成死循环) 

(aMenulnfo),此方法包含一个二维数组参数(传递按 

因此,本文采用上述表结构。对于要求层数更多的 

Menu

lD排列的菜单项信息),aMenulnfo(I,0)表示菜单编 

菜单结构,可以增加Menu—ID字腔的长度(例如l6即可 

号、aMertuIrtfo(I,1)表示菜单名称、aMe.nulafo(I, 表示模 

支持8级菜单结构J。 

维普资讯

块编号。 

的模块。 

该控件还包括一个事件MyClick(sModulelD As 

Event MyClick(ByVal sModulelD As StringJ 

Stirng),当点击节点时触发此事件,同时将节点对应的模 

块编号作为参数传递绐此事件,节点对应的模块编号在调 

Public Ftmction ShowMenu(aMenulnto)As Booleall 

用ShowMenu方法时被记录到每个节点的Tag属性中。 

Dimi AsLong 

控件中有一个ImageList含有3个图片(Open.bmp、 

Dim sMenulD As String 

Closedbmp、Module.bmp),分别对应打开、关闭的菜单 

Dim sParelltlDAs String 

项及底层的模块。 

Dim sMenuName As String 

Dim sModulelD As String 

3源代码 

图I,图2表示了组成菜 控件的两个控件的属性设 

On Error GoTo errHandle 

置,后面是完整的源代码。 

For i=0 To UBound(aMenulnfo1 

’取得菜单编号,菜单名称及模块编号 

sMenulD=aMenulnfo(I,0) 

sMelluName=aMenulnfo(i,1) 

sModulelD=aMenulnfo0,2 

If sMenulD=””Then ’加人根节点 

tvwMenu Nodes Add,”Root .sMenuName, 

’Closed’’ 

Else ’加八其他节点 

sParelltlD=Left(sMenulD.Len(sMenulD)一2) 

If sParelltID=””1lhen 

sParentlD=”ROOt” 

EndIf 

图1 ImageList控件 

If sModulelD=””Then ’非底层节点 

tvwMellu.Nodes Add sParendD,tvwChild, 

sMelluID sMenuName,”Closed’’ 

Else ’底层节点{即各个模块) 

tvwMenu.Nodes.Add sParentlD.tvwChild. 

sMenulD,sMenuName,”Module” 

’将最底层模块的编号记录到节点的Tag属 

性中 

tvwMenu Nodes(sMenulD).Tag=sModuleID 

EndIf 

EndIf 

Nexti 

图2 TreeView控件 

Option Explicit 

tvwMellu.Nodes(”Root”1 Expanded=True 

声明事件,该事件与TreeView控件的NodeClick事 

ShowMenu=True 

件关联, 

Exit Function 

同时将被点击模块的编号传递出击、以便调用相麻 

elfHandle: 

MsgBox”显示菜单项失败! &Chr(13)&Chr 

维普资讯

fl01&Err Description 

(c【1),这种开发方式相当于将每一模块独立调试、封装, 

ErrClear 

最后一并整合,可以避免大规模开发时变量命名冲突、难 

End Function 

干整合等问题。具体的工程文件信息如图3所示。 

Private Sub tvwMenu

NodeClick(ByVal Node As 

Node) 

IfTrim(Node.Tag、<>””Then 

RaiseEvent MyClick(Node Tag) 

EndIf 

End Sub 

Private Sub tvwMenu

Collapse(ByVal Node As 

ComctlLib.Node) 

Node Image:。’Closed’’ 

End Sub 

3 工 文件信思 

Private Sub tvwMenu

E Pand(ByVal Node As 

4 2 B,S架构 

ComcflLib.Node) 

该应用实例仍然由一个主画面(Main.htm)开始,其 

Node ExpandedImage=’ Open’’ 

中包含左右两帧,左帻(Manu asp)容纳菜单控件,右帧 

nEd Sub 

(fraModule)容纳各个模块,核心部分在左帧。 

Private Sub UserCo/itrol

Resize0 

显然菜单控件需要从数据库获取层级结构信息,控 

’使菜 显示区域与控件大小一致 

件又要下载到客户端运行,而B/S架构一般不光许在客户 

tvwMe/lu Width:UserContro1.Widfh 

端设置数据源,因此为了取得层级结构信息必须把数据传 

tvwMenu Height=UserControl Hei譬ht 

递到一个客户端脚本中的数组,然后在页面初始化时显示 

EndSub 

菜单 

具体实现的源代码略。● 

4应用示倒 

4.1 c,S架构 

该应用实例采用一个MDIForm作为主画面,主画面 

左侧放置上述的菜单控件,右侧是一个MDIChild宙体, 

负责显示各个模块 每个模块实际上就是一个大控件 


本文标签: 菜单 模块 编号 节点 控件