A simple XML-based module integration framework
1. 准备一个xml文件
xmlmenu
1<Menu> 2 <MenuItem Name="系统管理" AssemblyName="" FormTag="FALSE" AddToolbar="FALSE"> 3 <MenuItem Name="权限管理" ShortCut="" Image="" AssemblyName="" FormTag="FALSE" AddToolButton="FALSE"> 4 <MenuItem Name="系统权限管理" ShortCut="" Image="passWord.png" AssemblyName="HustCAD.IntePLM.WinUI.FrmSysRight,IntePLM.TyRightWinUI" FormTag="TRUE" AddToolButton="FALSE"/> 5 <MenuItem Name="权限规则定义" ShortCut="" Image="right.png" AssemblyName="HustCAD.IntePLM.WinUI.FrmRightRule,IntePLM.TyRightWinUI" FormTag="TRUE" AddToolButton="FALSE"/> 6 <MenuItem Name="权限日志" ShortCut="" Image="doc_yellow_edit.png" AssemblyName="HustCAD.IntePLM.WinUI.FrmRightLog,IntePLM.TyRightWinUI" FormTag="TRUE" AddToolButton="FALSE"/> 7 </MenuItem> 8</Menu>
2.准备一个xml schemal文件来验证xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!-- edited with XMLSpy v2006 sp2 U (http://www.altova.com) by peter (hust) -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="Menu">
<xs:complexType>
<xs:sequence>
<xs:element ref="MenuItem" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="MenuItem">
<xs:complexType>
<xs:sequence>
<xs:element ref="MenuItem" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="AddToolButton">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="TRUE"/>
<xs:enumeration value="FALSE"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="AddToolbar">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="TRUE"/>
<xs:enumeration value="FALSE"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="AssemblyName" type="xs:string" use="required"/>
<xs:attribute name="FormTag" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="TRUE"/>
<xs:enumeration value="FALSE"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Image" type="xs:string"/>
<xs:attribute name="Name" type="xs:string" use="required"/>
<xs:attribute name="ShortCut" use="optional">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="F1"/>
<xs:enumeration value="F2"/>
<xs:enumeration value="F3"/>
<xs:enumeration value="F4"/>
<xs:enumeration value="F5"/>
<xs:enumeration value="F6"/>
<xs:enumeration value="F7"/>
<xs:enumeration value="F8"/>
<xs:enumeration value="F9"/>
<xs:enumeration value="F10"/>
<xs:enumeration value="F11"/>
<xs:enumeration value="F12"/>
<xs:enumeration value="Alt0"/>
<xs:enumeration value="Alt1"/>
<xs:enumeration value="Alt2"/>
<xs:enumeration value="Alt3"/>
<xs:enumeration value="Alt4"/>
<xs:enumeration value="Alt5"/>
<xs:enumeration value="Alt6"/>
<xs:enumeration value="Alt7"/>
<xs:enumeration value="Alt8"/>
<xs:enumeration value="Alt9"/>
<xs:enumeration value="AltBksp"/>
<xs:enumeration value="AltF1"/>
<xs:enumeration value="AltF2"/>
<xs:enumeration value="AltF3"/>
<xs:enumeration value="AltF4"/>
<xs:enumeration value="AltF5"/>
<xs:enumeration value="AltF6"/>
<xs:enumeration value="AltF7"/>
<xs:enumeration value="AltF8"/>
<xs:enumeration value="AltF9"/>
<xs:enumeration value="AltF10"/>
<xs:enumeration value="AltF11"/>
<xs:enumeration value="AltF12"/>
<xs:enumeration value="AltDownArrow"/>
<xs:enumeration value="AltUpArrow"/>
<xs:enumeration value="AltLeftArrow"/>
<xs:enumeration value="AltRightArrow"/>
<xs:enumeration value="Ctrl0"/>
<xs:enumeration value="Ctrl1"/>
<xs:enumeration value="Ctrl2"/>
<xs:enumeration value="Ctrl3"/>
<xs:enumeration value="Ctrl4"/>
<xs:enumeration value="Ctrl5"/>
<xs:enumeration value="Ctrl6"/>
<xs:enumeration value="Ctrl7"/>
<xs:enumeration value="Ctrl8"/>
<xs:enumeration value="Ctrl9"/>
<xs:enumeration value="CtrlA"/>
<xs:enumeration value="CtrlB"/>
<xs:enumeration value="CtrlC"/>
<xs:enumeration value="CtrlD"/>
<xs:enumeration value="CtrlE"/>
<xs:enumeration value="CtrlF"/>
<xs:enumeration value="CtrlG"/>
<xs:enumeration value="CtrlH"/>
<xs:enumeration value="CtrlI"/>
<xs:enumeration value="CtrlJ"/>
<xs:enumeration value="CtrlK"/>
<xs:enumeration value="CtrlL"/>
<xs:enumeration value="CtrlM"/>
<xs:enumeration value="CtrlN"/>
<xs:enumeration value="CtrlO"/>
<xs:enumeration value="CtrlP"/>
<xs:enumeration value="CtrlQ"/>
<xs:enumeration value="CtrlR"/>
<xs:enumeration value="CtrlS"/>
<xs:enumeration value="CtrlT"/>
<xs:enumeration value="CtrlU"/>
<xs:enumeration value="CtrlV"/>
<xs:enumeration value="CtrlX"/>
<xs:enumeration value="CtrlY"/>
<xs:enumeration value="CtrlZ"/>
<xs:enumeration value="CtrlF1"/>
<xs:enumeration value="CtrlF2"/>
<xs:enumeration value="CtrlF3"/>
<xs:enumeration value="CtrlF4"/>
<xs:enumeration value="CtrlF5"/>
<xs:enumeration value="CtrlF6"/>
<xs:enumeration value="CtrlF7"/>
<xs:enumeration value="CtrlF8"/>
<xs:enumeration value="CtrlF9"/>
<xs:enumeration value="CtrlF10"/>
<xs:enumeration value="CtrlF11"/>
<xs:enumeration value="CtrlF12"/>
<xs:enumeration value="CtrlIns"/>
<xs:enumeration value="CtrlShift0"/>
<xs:enumeration value="CtrlShift1"/>
<xs:enumeration value="CtrlShift2"/>
<xs:enumeration value="CtrlShift3"/>
<xs:enumeration value="CtrlShift4"/>
<xs:enumeration value="CtrlShift5"/>
<xs:enumeration value="CtrlShift6"/>
<xs:enumeration value="CtrlShift7"/>
<xs:enumeration value="CtrlShift8"/>
<xs:enumeration value="CtrlShift9"/>
<xs:enumeration value="CtrlShiftA"/>
<xs:enumeration value="CtrlShiftB"/>
<xs:enumeration value="CtrlShiftC"/>
<xs:enumeration value="CtrlShiftD"/>
<xs:enumeration value="CtrlShiftE"/>
<xs:enumeration value="CtrlShiftF"/>
<xs:enumeration value="CtrlShiftG"/>
<xs:enumeration value="CtrlShiftH"/>
<xs:enumeration value="CtrlShiftI"/>
<xs:enumeration value="CtrlShiftJ"/>
<xs:enumeration value="CtrlShiftK"/>
<xs:enumeration value="CtrlShiftL"/>
<xs:enumeration value="CtrlShiftM"/>
<xs:enumeration value="CtrlShiftN"/>
<xs:enumeration value="CtrlShiftO"/>
<xs:enumeration value="CtrlShiftP"/>
<xs:enumeration value="CtrlShiftQ"/>
<xs:enumeration value="CtrlShiftR"/>
<xs:enumeration value="CtrlShiftS"/>
<xs:enumeration value="CtrlShiftT"/>
<xs:enumeration value="CtrlShiftU"/>
<xs:enumeration value="CtrlShiftV"/>
<xs:enumeration value="CtrlShiftW"/>
<xs:enumeration value="CtrlShiftX"/>
<xs:enumeration value="CtrlShiftY"/>
<xs:enumeration value="CtrlShiftZ"/>
<xs:enumeration value="ShiftIns"/>
<xs:enumeration value="ShiftF1"/>
<xs:enumeration value="ShiftF2"/>
<xs:enumeration value="ShiftF3"/>
<xs:enumeration value="ShiftF4"/>
<xs:enumeration value="ShiftF5"/>
<xs:enumeration value="ShiftF6"/>
<xs:enumeration value="ShiftF7"/>
<xs:enumeration value="ShiftF8"/>
<xs:enumeration value="ShiftF9"/>
<xs:enumeration value="ShiftF10"/>
<xs:enumeration value="ShiftF11"/>
<xs:enumeration value="ShiftF12"/>
<xs:enumeration value=""/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>3。定义一个类来加载菜单
public class MenuLoad
{
PRivate PluginCollection m_plugins = null;
public MenuBar _menbar = new MenuBar();
public ToolStrip _toolbar = new ToolStrip();
private OutlookBar bar = new OutlookBar();
private ImageList imglist = new ImageList();
private StringBuilder builder = new StringBuilder();
public MenuLoad()
{
bar = _menbar.outlookBar;
}
private TabControl tabCtrl;
public TabControl TabCtrl
{
set
{
tabCtrl = value;
}
}
private void ValidationEventHandler(object sender, ValidationEventArgs e)
{
builder.AppendLine("验证XML文档的时候发生错误:");
builder.AppendLine("严重级别:" + e.Severity);
builder.AppendLine("错误信息:" + e.Message);
builder.AppendLine("------+--------+-------+------+--------+-------+------+--------+-------+");
builder.AppendLine();
}
/**//// <summary>
/// 验证XML文件是否是合乎规范的文件
/// </summary>
/// <param name="xmlfile">文件名称</param>
/// <returns>是则返回true,否则返回false</returns>
private bool ValidateXml(string xmlfile)
{
bool validXml = false;
string spath = "";
spath = application.StartupPath + "\\configurations\\XMLSMenu.xsd";
if(!System.IO.File.Exists(spath))
{
throw new System.IO.FileNotFoundException(String.Format(Resources.StringFileNotFound, spath));
}
XmlReaderSettings settings = new XmlReaderSettings();
XmlSchemaSet schemaSet = new XmlSchemaSet();
schemaSet.Add(null, spath);
settings.Schemas.Add(schemaSet);
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += new ValidationEventHandler(ValidationEventHandler);
settings.ValidationFlags = settings.ValidationFlags | XmlSchemaValidationFlags.ReportValidationWarnings;
XmlReader reader = XmlReader.Create(xmlfile, settings);
while(reader.Read())
{
}
if(builder.Length > 0)
{
validXml = false;
}
else
{
validXml = true;
}
reader.Close();
return validXml;
}
/**//// <summary>
/// 加载菜单
/// </summary>
/// <param name="main">主菜单</param>
/// <param name="xmlfile">菜单定义文件</param>
public MainMenu LoadMenus(string xmlfile)
{
MainMenu mainmenu = new MainMenu();
try
{
using(new WaitCursor())
{
//验证XML是否是合乎规范的XML文件
if(ValidateXml(xmlfile))
{
XmlDocument document = new XmlDocument();
document.Load(xmlfile);
XmlNode rootNode = document.DocumentElement;
mainmenu = GetMenus(rootNode);
}
else
{
throw new Exception(builder.ToString());
}
}
}
catch (System.IO.FileNotFoundException)
{
Utility.ShowErrorMsg(String.Format(Resources.StringFileNotFound, xmlfile));
}
return mainmenu;
}
/**//// <summary>
/// 加载菜单
/// </summary>
/// <param name="main">主菜单</param>
/// <param name="node">菜单项节点</param>
private MainMenu GetMenus(XmlNode node)
{
MainMenu mainmenu = new MainMenu();
List<XmlNode> nodelist= new List<XmlNode>();
List<OfficeMenuItem> mnulist = new List<OfficeMenuItem>();
List<IconPanel> iplist = new List<IconPanel>();
string menutext ="";
//首先加载主菜单,避免迭代的时候菜单显示的过分延迟。
foreach(XmlNode child in node.ChildNodes)
{
if(child.NodeType == XmlNodeType.Element && child.Name == "MenuItem")
{
menutext = child.Attributes["Name"].Value;
OfficeMenuItem item = new OfficeMenuItem(true,menutext);
mainmenu.MenuItems.Add(item);
IconPanel cp = new IconPanel();
bar.AddBand(menutext, cp);
nodelist.Add(child);
mnulist.Add(item);
iplist.Add(cp);
}
}
//加载所有的子菜单
GetSubMenus(iplist.ToArray(),mnulist.ToArray(), nodelist.ToArray());
return mainmenu;
}
/**//// <summary>
/// 加载所有子菜单
/// </summary>
/// <param name="main">主菜单集合</param>
/// <param name="node">菜单节点集合</param>
private void GetSubMenus(IconPanel[] iplist ,OfficeMenuItem[] main, XmlNode[] node)
{
EventHandler handler = new EventHandler(OnPluginClick);
EventHandler handler1 = new EventHandler(OnIconClick);
EventHandler handler2 = new EventHandler(OnButtonClick);
string asmname;
string formtag;
string text;
MenuClass mc;
XmlNode child;
string iconpath = "";
string iconname = "";
string msc = "";
for(int i = 0; i <= main.GetUpperBound(0); i++)
{
//foreach(XmlNode child in node[i].ChildNodes)
for(int j = 0; j < node[i].ChildNodes.Count;j++ )
{
child = node[i].ChildNodes[j];
if(child.NodeType == XmlNodeType.Element && child.Name == "MenuItem")
{
asmname = child.Attributes["AssemblyName"].Value;
formtag = child.Attributes["FormTag"].Value;
text = child.Attributes["Name"].Value;
msc = child.Attributes["ShortCut"].Value;
OfficeMenuItem item = new OfficeMenuItem(true, text, handler);
iconname = child.Attributes["Image"].Value;
if(iconname != string.Empty)
{
iconpath = Themes.GetCurrentThemePath() +iconname;
item.IconPath = iconpath;
}
mc = new MenuClass();
mc.Assemblyname = asmname;
mc.FormTag = formtag;
item.Tag = mc;
if(msc != string.Empty)
{
item.Shortcut = MenuShortCut.GetShortCut(msc);
}
main[i].MenuItems.Add(item);
if((iconpath != string.Empty) && System.IO.File.Exists(iconpath))
{ //添加按钮到OutlookBar
PanelIcon picon = iplist[i].AddIcon(item.Text,Image.FromFile(iconpath),handler1);
picon.Tag = mc;
//添加按钮到toolbar
ToolStripButton button = new ToolStripButton(item.Text, Image.FromFile(iconpath), handler2);
button.DisplayStyle = ToolStripItemDisplayStyle.Image;
button.ToolTipText = item.Text;
button.Tag = mc;
button.Visible = true;
_toolbar.Items.Add(button);
}
iconpath = "";
mc = null;
if(child.ChildNodes.Count > 0)
{
GetChildMenu(iplist[i],item, child);
}
}
}
//添加分割线
ToolStripSeparator ss = new ToolStripSeparator();
_toolbar.Items.Add(ss);
}
}
/**//// <summary>
/// 加载子菜单
/// </summary>
/// <param name="parent">父菜单</param>
/// <param name="node">父菜单定义XML节点</param>
private void GetChildMenu(IconPanel ip,OfficeMenuItem parent, XmlNode node)
{
EventHandler handler = new EventHandler(OnPluginClick);
EventHandler handler1 = new EventHandler(OnIconClick);
EventHandler handler2 = new EventHandler(OnButtonClick);
MenuClass mc;
string asmname;
string formtag;
string text;
XmlNode child1;
string iconpath = "";
string iconname = "";
string msc = "";
//foreach(XmlNode child1 in node.ChildNodes)
for(int i = 0; i < node.ChildNodes.Count - 1;i++ )
{
child1 = node.ChildNodes[i];
//检查是否提供了类型
asmname = child1.Attributes["AssemblyName"].Value;
formtag = child1.Attributes["FormTag"].Value;
text = child1.Attributes["Name"].Value;
OfficeMenuItem childitem;
childitem = new OfficeMenuItem(true, text, handler);
childitem.Name = text;
mc = new MenuClass();
mc.Assemblyname = asmname;
mc.FormTag = formtag;
childitem.Tag = mc;
//添加快捷键
msc = child1.Attributes["ShortCut"].Value;
if(msc != string.Empty)
{
childitem.Shortcut = MenuShortCut.GetShortCut(msc);
}
//添加图标
iconname = child1.Attributes["Image"].Value;
if(iconname != string.Empty)
{
iconpath = Themes.GetCurrentThemePath() + iconname;
childitem.IconPath = iconpath;
}
parent.MenuItems.Add(childitem);
if((iconpath != string.Empty) && System.IO.File.Exists(iconpath))
{ //添加按钮到OutlookBar
PanelIcon picon = ip.AddIcon(childitem.Text, Image.FromFile(iconpath), handler1);
picon.Tag = mc;
//添加按钮到toolbar
ToolStripButton button = new ToolStripButton(childitem.Text, Image.FromFile(iconpath), handler2);
button.DisplayStyle = ToolStripItemDisplayStyle.Image;
button.ToolTipText = childitem.Text;
button.Tag = mc;
button.Visible = true;
_toolbar.Items.Add(button);
}
iconpath = "";
mc = null;
if(child1.ChildNodes.Count > 0)
{
GetChildMenu(ip,childitem, child1);
}
}
}
/**//// <summary>
/// 打开一个窗体
/// </summary>
/// <param name="asmname">窗体类程序集和窗体类的组合,从节点的AssemblyName属性获取</param>
private void OpenForm(MenuClass mc)
{
string asmname = mc.Assemblyname;
string formtag = mc.FormTag;
if (formtag == "")
{
throw new Exception(Resources.StringNoFormFlag);
}
if(formtag.ToUpper() == "TRUE")
{
if(asmname == string.Empty)
{
throw new NullReferenceException(Resources.StringAssemblyNull);
}
//string[] a = asmname.Split(',');
object obj = null;
Type tp = Type.GetType(asmname);
if(tp != null)
{
obj = Activator.CreateInstance(tp);
}
else
{
throw new Exception("加载程序的时候出错,请检查程序(dll,exe)是否存在或者类型是否正确。");
}
//检查是否是Form类
if((obj == null) | !(obj is Form))
{
throw new Exception(Resources.StringNotForm);
}
Form frm = (obj as Form);
//检查打开的第一个窗口是否是MDIFORM
if(Application.OpenForms[0].IsMdiContainer)
{
//作为MDICHILDFORM
frm.MdiParent = Application.OpenForms[0];
}
//加载窗体
frm.Show();
}
}
/**//// <summary>
/// 菜单单击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void OnPluginClick(object sender, EventArgs args)
{
OfficeMenuItem item = (OfficeMenuItem)sender;
MenuClass mc = (MenuClass) item.Tag;
if ((item.Text == "退出") | (item.Text == "EXIT"))
{
OnExitClick(sender, args);
return;
}
OpenForm(mc);
}
}这里面用到了delegate,最重要的函数是加载菜单的函数和OnPluginClick函数。
使用这个框架可以动态增加任意的层次的模块。
微软的CAB 使用Resigster site方式来增加模块,感觉不是很方便。
以上就是一个简单的基于XML的模块集成框架的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!
Hot AI Tools
Undress AI Tool
Undress images for free
AI Clothes Remover
Online AI tool for removing clothes from photos.
Undresser.AI Undress
AI-powered app for creating realistic nude photos
ArtGPT
AI image generator for creative art from text prompts.
Stock Market GPT
AI powered investment research for smarter decisions
Hot Article
Popular tool
Notepad++7.3.1
Easy-to-use and free code editor
SublimeText3 Chinese version
Chinese version, very easy to use
Zend Studio 13.0.1
Powerful PHP integrated development environment
Dreamweaver CS6
Visual web development tools
SublimeText3 Mac version
God-level code editing software (SublimeText3)
Hot Topics
20446
7
13592
4
JSON vs. XML: Why RSS Chose XML
May 05, 2025 am 12:01 AM
RSS chose XML instead of JSON because: 1) XML's structure and verification capabilities are better than JSON, which is suitable for the needs of RSS complex data structures; 2) XML was supported extensively at that time; 3) Early versions of RSS were based on XML and have become a standard.
Understanding RSS Documents: A Comprehensive Guide
May 09, 2025 am 12:15 AM
RSS documents are a simple subscription mechanism to publish content updates through XML files. 1. The RSS document structure consists of and elements and contains multiple elements. 2. Use RSS readers to subscribe to the channel and extract information by parsing XML. 3. Advanced usage includes filtering and sorting using the feedparser library. 4. Common errors include XML parsing and encoding issues. XML format and encoding need to be verified during debugging. 5. Performance optimization suggestions include cache RSS documents and asynchronous parsing.
Building XML Applications with C : Practical Examples
May 03, 2025 am 12:16 AM
You can use the TinyXML, Pugixml, or libxml2 libraries to process XML data in C. 1) Parse XML files: Use DOM or SAX methods, DOM is suitable for small files, and SAX is suitable for large files. 2) Generate XML file: convert the data structure into XML format and write to the file. Through these steps, XML data can be effectively managed and manipulated.
RSS, XML and the Modern Web: A Content Syndication Deep Dive
May 08, 2025 am 12:14 AM
RSS and XML are still important in the modern web. 1.RSS is used to publish and distribute content, and users can subscribe and get updates through the RSS reader. 2. XML is a markup language and supports data storage and exchange, and RSS files are based on XML.
XML in C : Handling Complex Data Structures
May 02, 2025 am 12:04 AM
Working with XML data structures in C can use the TinyXML or pugixml library. 1) Use the pugixml library to parse and generate XML files. 2) Handle complex nested XML elements, such as book information. 3) Optimize XML processing code, and it is recommended to use efficient libraries and streaming parsing. Through these steps, XML data can be processed efficiently.
Beyond Basics: Advanced RSS Features Enabled by XML
May 07, 2025 am 12:12 AM
RSS enables multimedia content embedding, conditional subscription, and performance and security optimization. 1) Embed multimedia content such as audio and video through tags. 2) Use XML namespace to implement conditional subscriptions, allowing subscribers to filter content based on specific conditions. 3) Optimize the performance and security of RSSFeed through CDATA section and XMLSchema to ensure stability and compliance with standards.
Understanding RSS: An XML Perspective
Apr 25, 2025 am 12:14 AM
RSS is an XML-based format used to publish frequently updated content. 1. RSSfeed organizes information through XML structure, including title, link, description, etc. 2. Creating RSSfeed requires writing in XML structure, adding metadata such as language and release date. 3. Advanced usage can include multimedia files and classified information. 4. Use XML verification tools during debugging to ensure that the required elements exist and are encoded correctly. 5. Optimizing RSSfeed can be achieved by paging, caching and keeping the structure simple. By understanding and applying this knowledge, content can be effectively managed and distributed.
Inside the RSS Document: Essential XML Tags and Attributes
May 03, 2025 am 12:12 AM
The core structure of RSS documents includes XML tags and attributes. The specific parsing and generation steps are as follows: 1. Read XML files, process and tags. 2. Extract,,, etc. tag information. 3. Handle custom tags and attributes to ensure version compatibility. 4. Use cache and asynchronous processing to optimize performance to ensure code readability.




