我正在尝试创建一个使用工具striplabels和toolstripmenuitems的表单菜单。我想从XML文件中喂食信息以及结构,以便在更新XML文件时,菜单会动态更新。我已经开始对其进行编码,但是正在努力寻找映射数据的最佳方法,因此在菜单中具有正确的结构以遵循XML结构。
例如(为简单起见(,我的XML文件可以是
<?xml version="1.0" encoding="UTF-8"?>
<Menu1>
<subMenu1>
<subSubMenu1>1</subSubMenu1>
</subMenu1>
</Menu1>
我想在woolstriplabel1,woolstripmenu1中的子菜单和subsubmenu1中映射菜单1,在toolstripmenuitem1中 - 和toolstriptextbox中的" 1"。
我会稍微更改您的XML结构,因为这有点令人困惑。而不是将1
标识符放在元素名称中,而是将其放在属性中。我想这应该是菜单文本,所以我给了它们一些结构上的名称。
好吧,这是我想出的
<?xml version="1.0" encoding="utf-8"?>
<Menu>
<MenuItem Text="SubMenu1">
<MenuItem Text="SubSubMenu1" TextBox="abc"/>
<MenuItem Text="SubSubMenu2">
<MenuItem Text="SubSubSubMenu1" TextBox="def">
<MenuItem Text="SubSubSubSubMenu1"/>
<MenuItem Text="SubSubSubSubMenu2"/>
<MenuItem Text="SubSubSubSubMenu3" TextBox="ghi"/>
<MenuItem Text="SubSubSubSubMenu4"/>
</MenuItem>
<MenuItem Text="SubSubSubMenu2"/>
</MenuItem>
</MenuItem>
<MenuItem Text="SubMenu2">
<MenuItem Text="SubSubMenu1"/>
</MenuItem>
</Menu>
这些类是可用于从XML文件中进行序列化并保持状态
的类<XmlRoot>
Public Class Menu
<XmlElement("MenuItem")>
Public MenuItems As List(Of MenuItem)
End Class
Public Class MenuItem
<XmlAttribute>
Public Text As String
<XmlAttribute>
Public TextBox As String
<XmlElement("MenuItem")>
Public MenuItems As List(Of MenuItem)
Public Function CreateToolStripMenuItem(isSubMenu As Boolean) As ToolStripMenuItem
Dim tsmi = New ToolStripMenuItem(Me.Text)
If isSubMenu Then AddHandler tsmi.Click, Sub(sender As Object, e As EventArgs) MessageBox.Show($"You clicked {DirectCast(sender, ToolStripMenuItem).Text}")
If Me.TextBox <> "" Then
Dim tb = New ToolStripTextBox() With {.Text = Me.TextBox}
'tb.ReadOnly = True
tsmi.DropDownItems.Add(tb)
End If
If Me.MenuItems.Any Then
For Each mi In Me.MenuItems
tsmi.DropDownItems.Add(mi.CreateToolStripMenuItem(True))
Next
End If
Return tsmi
End Function
End Class
和一些测试代码。您只需要使用此代码来测试它的空表格,以及一个可以加载" filename.xml"
的XML文件Option Strict On
Imports System.IO
Imports System.Xml.Serialization
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
loadMenus()
End Sub
Private Sub loadMenus()
Dim s = New XmlSerializer(GetType(Menu))
Dim menu As Menu
Using sr = New StreamReader("filename.xml")
menu = CType(s.Deserialize(sr), Menu)
End Using
Dim ms = New MenuStrip()
For Each item In menu.MenuItems
ms.Items.Add(item.CreateToolStripMenuItem(False))
Next
ms.Visible = True
Me.Controls.Add(ms)
End Sub
End Class
它使用递归,因此XML和.NET中只有一个菜单类,您可以具有任何级别的菜单深度。
支持在代码中添加单击事件处理程序。由您使用或不使用它。