我正在尝试创建一个使用ToolStripLabels和ToolStripMenuItems的表单菜单。我想提供来自XML文件的信息和结构,这样当我更新XML文件时,菜单就会动态更新。我已经开始对它进行编码,但是我正在努力寻找映射数据的最佳方法,从而在菜单中具有正确的结构来遵循XML结构。
例如(为了简单起见),我的XML文件可以是
<?xml version="1.0" encoding="UTF-8"?>
<Menu1>
<subMenu1>
<subSubMenu1>1</subSubMenu1>
</subMenu1>
</Menu1>我希望将Menu1映射到ToolStripLabel1中,将subMenu映射到ToolStripMenu1中,将subSubMenu1映射到ToolStripMenuItem1中--并在ToolStripTextBox中映射"1“。
发布于 2019-05-25 05:39:39
我会稍微改变一下您的XML结构,因为它有点混乱。不是将1标识符放在元素名称中,而是放在属性中。我猜它应该是菜单文本,所以我给它们起了一些结构名称。
下面是我想出的一些XML
<?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中只有一个菜单类,并且可以有任何级别的菜单深度。
支持在代码中添加单击事件处理程序。这取决于你是否使用它。
https://stackoverflow.com/questions/56298549
复制相似问题