详细概括VB.NET实现动态菜单的方法

开发 后端
这里介绍VB.NET实现动态菜单,这个例子实现了VB.NET实现动态菜单,用户可以在当前菜单的任意一个节点上添加一个子菜单,并为添加的子菜单添加事件。

VB.NET经过长时间的发展,很多用户都很了解VB.NET实现动态菜单了,这里我发表一下个人理解,和大家讨论讨论。自己写了一个VB.NET实现动态菜单的例子,觉得还不错。例子中用的主要技术有:
◆菜单树的操作
◆treeview的操作
◆利用堆栈实现菜单树与treeview树成员的对应
◆利用委托实现对象与事件的关联

因为我也是初学者,所以有些词汇用得可能不恰当,另外有些理解也可能有偏差。这个例子实现了VB.NET实现动态菜单,用户可以在当前菜单的任意一个节点上添加一个子菜单,并为添加的子菜单添加事件。

例子介绍如下:

首先创建一个 VB.NET winform application

在form中添加一个菜单,取名为:MainItem,随便添加几个菜单项几项。
◆添加一个textbox控件, 取名为:txtNewText
◆添加一个listbox控件, 取名为:lstHandlers
◆添加一个TreeView控件,取名为:tvMenu

具体代码如下(其中有大部分代码为自动生成):

  1. Public Class Form1Class Form1  
  2. Inherits System.Windows.Forms.Form  
  3.  
  4. Windows 窗体设计器生成的代码#Region " Windows 窗体设计器生成的代码 "  
  5.  
  6. Public Sub New()Sub New()  
  7. MyBase.New()  
  8.  
  9. '该调用是 Windows 窗体设计器所必需的。  
  10. InitializeComponent()  
  11.  
  12. '在 InitializeComponent() 调用之后添加任何初始化  
  13.  
  14. End Sub  
  15.  
  16. '窗体重写处置以清理组件列表。  
  17. Protected Overloads Overrides Sub Dispose()Sub Dispose(ByVal disposing As Boolean)  
  18. If disposing Then  
  19. If Not (components Is Nothing) Then  
  20. components.Dispose()  
  21. End If  
  22. End If  
  23. MyBase.Dispose(disposing)  
  24. End Sub  
  25.  
  26. 'Windows 窗体设计器所必需的  
  27. Private components As System.ComponentModel.IContainer  
  28.  
  29. '注意:以下过程是 Windows 窗体设计器所必需的  
  30. '可以使用 Windows 窗体设计器修改此过程。  
  31. '不要使用代码编辑器修改它。  
  32. Friend WithEvents MainMenu As System.Windows.Forms.MainMenu  
  33. Friend WithEvents MenuItem1 As System.Windows.Forms.MenuItem  
  34. Friend WithEvents MenuItem2 As System.Windows.Forms.MenuItem  
  35. Friend WithEvents MenuItem3 As System.Windows.Forms.MenuItem  
  36. Friend WithEvents lstHandlers As System.Windows.Forms.ListBox  
  37. Friend WithEvents Label3 As System.Windows.Forms.Label  
  38. Friend WithEvents tvMenu As System.Windows.Forms.TreeView  
  39. Friend WithEvents Label2 As System.Windows.Forms.Label  
  40. Friend WithEvents Label1 As System.Windows.Forms.Label  
  41. Friend WithEvents txtNewText As System.Windows.Forms.TextBox  
  42. Friend WithEvents btnAddItem As System.Windows.Forms.Button  
  43. <System.Diagnostics.DebuggerStepThrough()> 
    Private Sub InitializeComponent()Sub InitializeComponent()  
  44. Me.components = New System.ComponentModel.Container  
  45. Me.MainMenu = New System.Windows.Forms.MainMenu(Me.components)  
  46. Me.MenuItem1 = New System.Windows.Forms.MenuItem  
  47. Me.MenuItem2 = New System.Windows.Forms.MenuItem  
  48. Me.MenuItem3 = New System.Windows.Forms.MenuItem  
  49. Me.lstHandlers = New System.Windows.Forms.ListBox  
  50. Me.Label3 = New System.Windows.Forms.Label  
  51. Me.tvMenu = New System.Windows.Forms.TreeView  
  52. Me.Label2 = New System.Windows.Forms.Label  
  53. Me.Label1 = New System.Windows.Forms.Label  
  54. Me.txtNewText = New System.Windows.Forms.TextBox  
  55. Me.btnAddItem = New System.Windows.Forms.Button  
  56. Me.SuspendLayout()  
  57. '  
  58. 'MainMenu  
  59. '  
  60. Me.MainMenu.MenuItems.AddRange
    (New System.Windows.Forms.MenuItem() {Me.MenuItem1, Me.MenuItem2, Me.MenuItem3})  
  61. '  
  62. 'MenuItem1  
  63. '  
  64. Me.MenuItem1.Index = 0 
  65. Me.MenuItem1.Text = "菜单1" 
  66. '  
  67. 'MenuItem2  
  68. '  
  69. Me.MenuItem2.Index = 1 
  70. Me.MenuItem2.Text = "菜单2" 
  71. '  
  72. 'MenuItem3  
  73. '  
  74. Me.MenuItem3.Index = 2 
  75. Me.MenuItem3.Text = "菜单3" 
  76. '  
  77. 'lstHandlers  
  78. '  
  79. Me.lstHandlers.ItemHeight = 12 
  80. Me.lstHandlers.Location = New System.Drawing.Point(88, 64)  
  81. Me.lstHandlers.Name = "lstHandlers" 
  82. Me.lstHandlers.Size = New System.Drawing.Size(136, 112)  
  83. Me.lstHandlers.TabIndex = 13 
  84. '  
  85. 'Label3  
  86. '  
  87. Me.Label3.Location = New System.Drawing.Point(56, 64)  
  88. Me.Label3.Name = "Label3" 
  89. Me.Label3.Size = New System.Drawing.Size(32, 16)  
  90. Me.Label3.TabIndex = 12 
  91. Me.Label3.Text = "事件" 
  92. '  
  93. 'tvMenu  
  94. '  
  95. Me.tvMenu.Location = New System.Drawing.Point(280, 24)  
  96. Me.tvMenu.Name = "tvMenu" 
  97. Me.tvMenu.Size = New System.Drawing.Size(152, 152)  
  98. Me.tvMenu.TabIndex = 11 
  99. '  
  100. 'Label2  
  101. '  
  102. Me.Label2.Location = New System.Drawing.Point(232, 32)  
  103. Me.Label2.Name = "Label2" 
  104. Me.Label2.Size = New System.Drawing.Size(48, 16)  
  105. Me.Label2.TabIndex = 10 
  106. Me.Label2.Text = "添加到" 
  107. '  
  108. 'Label1  
  109. '  
  110. Me.Label1.Location = New System.Drawing.Point(8, 32)  
  111. Me.Label1.Name = "Label1" 
  112. Me.Label1.Size = New System.Drawing.Size(80, 16)  
  113. Me.Label1.TabIndex = 9 
  114. Me.Label1.Text = "新菜单项文字" 
  115. '  
  116. 'txtNewText  
  117. '  
  118. Me.txtNewText.Location = New System.Drawing.Point(88, 24)  
  119. Me.txtNewText.Name = "txtNewText" 
  120. Me.txtNewText.Size = New System.Drawing.Size(136, 21)  
  121. Me.txtNewText.TabIndex = 8 
  122. '  
  123. 'btnAddItem  
  124. '  
  125. Me.btnAddItem.Location = New System.Drawing.Point(168, 192)  
  126. Me.btnAddItem.Name = "btnAddItem" 
  127. Me.btnAddItem.Size = New System.Drawing.Size(80, 24)  
  128. Me.btnAddItem.TabIndex = 7 
  129. Me.btnAddItem.Text = "添加菜单项" 
  130. '  
  131. 'Form1  
  132. '  
  133. Me.AutoScaleBaseSize = New System.Drawing.Size(6, 14)  
  134. Me.ClientSize = New System.Drawing.Size(448, 225)  
  135. Me.Controls.Add(Me.lstHandlers)  
  136. Me.Controls.Add(Me.Label3)  
  137. Me.Controls.Add(Me.tvMenu)  
  138. Me.Controls.Add(Me.Label2)  
  139. Me.Controls.Add(Me.Label1)  
  140. Me.Controls.Add(Me.txtNewText)  
  141. Me.Controls.Add(Me.btnAddItem)  
  142. MeMe.Menu = Me.MainMenu  
  143. Me.Name = "Form1" 
  144. Me.Text = "Form1" 
  145. Me.ResumeLayout(False)  
  146. Me.PerformLayout()  
  147.  
  148. End Sub  
  149.  
  150. #End Region  
  151.  
  152. Private eHandlers(3) As EventHandler '定义事件方法集合  
  153. Private Sub ShowHelloWorld()Sub ShowHelloWorld(ByVal sender As System.Object, 
    ByVal e As System.EventArgs)  
  154. MessageBox.Show("Hello World!")  
  155. End Sub  
  156. Private Sub ShowMenuItemText()Sub ShowMenuItemText(ByVal sender As System.Object, 
    ByVal e As System.EventArgs)  
  157. Dim mItem As MenuItem  
  158. mItem = CType(sender, MenuItem)  
  159. MessageBox.Show(mItem.Text)  
  160. End Sub  
  161. Private Sub ShowMenuItemIndex()Sub ShowMenuItemIndex(ByVal sender As System.Object, 
    ByVal e As System.EventArgs)  
  162. Dim mItem As MenuItem  
  163.  
  164. mItem = CType(sender, MenuItem)  
  165. MessageBox.Show(mItem.Index)  
  166. End Sub  
  167. Private Sub ShowCurDateTime()Sub ShowCurDateTime(ByVal sender As System.Object, 
    ByVal e As System.EventArgs)  
  168. Dim strDate As String = DateTime.Now.ToString()  
  169. MessageBox.Show(strDate)  
  170. End Sub  
  171.  
  172.  
  173. Private Sub MenuItemToNode()Sub MenuItemToNode(ByVal menuItems As Menu.MenuItemCollection, 
    ByVal targetNodes As TreeNodeCollection)  
  174. 'TreeNodeCollection 代表一个树结点集合,每一个节点下的儿子节点的集合  
  175. 'MenuItemCollection 代表一个菜单项的集合,也是菜单树中某一菜单下的一级子菜单的菜单项的集合  
  176. Dim subItem As MenuItem  
  177. For Each subItem In menuItems  
  178. Dim subNode As New TreeNode(subItem.Text)  
  179. If subItem.MenuItems.Count > 0 Then  
  180. MenuItemToNode(subItem.MenuItems, subNode.Nodes)'递归处理  
  181. End If  
  182. targetNodes.Add(subNode)  
  183. Next  
  184. End Sub  
  185.  
  186. Private Function FindMenuItem()Function FindMenuItem(ByVal selectedNode As TreeNode) As MenuItem  
  187. Dim indexStack As New Collections.Stack()'定一个堆栈对象  
  188. '将树结点从当前节点一直到根的一条路径压入堆栈  
  189. Do Until selectedNode Is Nothing  
  190. indexStack.Push(selectedNode.Index)  
  191. selectedNodeselectedNode = selectedNode.Parent  
  192. Loop  
  193. '再利用菜单与treeview树一一对应的特点.根据节点的index,找到对应的菜单项.然后沿着路径找到当前的菜单项  
  194. Dim menuItem As MenuItem = MainMenu.MenuItems(indexStack.Pop())  
  195. Do Until indexStack.Count = 0 
  196. menuItemmenuItem = menuItem.MenuItems(indexStack.Pop())  
  197. Loop  
  198. '返回当前菜单项  
  199. Return menuItem  
  200.  
  201. End Function  
  202.  
  203. Private Sub btnAddItem_Click()Sub btnAddItem_Click(ByVal sender As System.Object, 
    ByVal e As System.EventArgs) Handles btnAddItem.Click  
  204. If txtNewText.Text = "" Then Exit Sub  
  205. If tvMenu.SelectedNode Is Nothing Then Exit Sub  
  206.  
  207. Dim correspondingMenuItem As MenuItem  
  208. Dim newMenuItem As MenuItem  
  209. correspondingMenuItem = FindMenuItem(tvMenu.SelectedNode)'将节点转成菜单项  
  210.  
  211. newMenuItem = New MenuItem(txtNewText.Text) '生成新加的菜单项  
  212. If lstHandlers.SelectedIndex >= 0 Then  
  213. AddHandler newMenuItem.Click, eHandlers(lstHandlers.SelectedIndex) '建立事件的委托  
  214. End If  
  215. correspondingMenuItem.MenuItems.Add(newMenuItem)'将新菜单加到菜单树中  
  216. tvMenu.Nodes.Clear() '清空treeview树  
  217. MenuItemToNode(MainMenu.MenuItems, tvMenu.Nodes) '将最新的菜单呈现成树  
  218. tvMenu.ExpandAll() '展开树  
  219. End Sub  
  220.  
  221. Private Sub Form1_Load()Sub Form1_Load(ByVal sender As System.Object, 
    ByVal e As System.EventArgs) Handles MyBase.Load  
  222. MenuItemToNode(MainMenu.MenuItems, tvMenu.Nodes)'将菜单树呈现到treeview中  
  223. tvMenu.ExpandAll() '展开他  
  224.  
  225. '将三个事件方法放入集合  
  226. eHandlers(0) = AddressOf ShowHelloWorld  
  227. eHandlers(1) = AddressOf ShowMenuItemText  
  228. eHandlers(2) = AddressOf ShowMenuItemIndex  
  229. eHandlers(3) = AddressOf ShowCurDateTime  
  230. '将事件方法名字写入列表  
  231. Dim i As Integer  
  232. For i = 0 To eHandlers.Length - 1  
  233. lstHandlers.Items.Add(eHandlers(i).Method.Name)  
  234. Next  
  235. End Sub  
  236. End Class  

【编辑推荐】

  1. VB.NET水印类整合水印技术
  2. 实例讲述VB.NET使用Log4Net
  3. 浅析利用VB.NET启动Smartphone常规方法
  4. 三分钟学会VB.NET转换形态
  5. 自己动手改写VB.NET内存指针
责任编辑:佚名 来源: 赛迪网
相关推荐

2009-11-03 10:00:20

VB.NET New方

2009-10-27 11:32:42

VB.NET Disp

2009-11-03 10:51:33

VB.NET共享

2009-10-14 16:46:25

VB.NET OnSt

2010-01-12 15:54:47

VB.NET动态控件数

2009-10-29 16:23:42

VB.NET实现IEn

2009-10-12 15:02:51

VB.NET动态控件

2009-10-13 14:50:59

VB.NET Envi

2009-10-14 14:04:29

VB.NET创建Web

2009-10-26 15:57:07

VB.NET使用Ora

2009-10-14 10:19:57

VB.NET Doma

2009-10-15 17:50:48

VB.NET Spli

2010-01-22 18:14:49

VB.NET菜单组件

2009-10-14 15:34:29

VB.NET窗体编程模

2009-10-14 13:15:09

VB.NET数据绑定

2009-10-28 10:51:32

VB.NET默认属性

2009-11-10 12:42:47

VB.NET Prin

2009-10-21 10:05:30

VB.NET运行环境

2009-10-23 14:06:07

VB.NET类对象

2009-10-15 10:09:14

PCC和桌面电脑VB.NET实现
点赞
收藏

51CTO技术栈公众号