您好,欢迎访问一九零五行业门户网

一个简单的基于XML的模块集成框架

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的模块集成框架的内容。
其它类似信息

推荐信息