C#实现基于XML配置MenuStrip菜单的方法
本文实例讲述了c#实现基于xml配置menustrip菜单的方法。分享给大家供大家参考。具体如下:
1.关于本程序的说明
用xml配置menustrip菜单,本程序只是提供一个思路。程序在load函数中根据xml文件中的设置动态生成一个menustrip组件的items集合。
程序示例如下:
2.使用到的xml文档示例
<?xml version="1.0" encoding="gb2312"?> <!--menustrip:mnsmainmenu控件中的各个菜单配置--> <!--menu:菜单栏中的各项,text:显示名称,shortkey:快捷键--> <menustrip> <menu text="文件(file)" shortkey="alt+f"> <item type="menuitem" text="修改窗口颜色"> <item type="menuitem" text="红色" shortkey="shift+f6" functionattribute="colortored" /> <item type="menuitem" text="绿色" shortkey="shift+f7" functionattribute="colortolawngreen" /> </item> <item type="seperator" /> <item type="menuitem" text="普通" shortkey="ctrl+shift+x" functionattribute="formnormal" /> <item type="menuitem" text="最小化" shortkey="ctrl+shift+y" functionattribute="formminimize" /> <item type="menuitem" text="最大化" shortkey="ctrl+shift+z" functionattribute="formmaximize" /> <item type="seperator" /> <item type="menuitem" text="关闭" shortkey="alt+f4" functionattribute="formclose" /> </menu> <menu text="帮助(help)" shortkey="alt+f"> <item type="menuitem" text="关于" functionattribute="formabout" /> </menu> </menustrip>
配置规则:
①.所有的内容都在标签<menustrip>中
②.每一个<menu>标签代表了一个横向的菜单项,其中text属性是显示的文字,shortkey属性是选择用的快捷键
③.每一个<item>标签都在<menu>或<item>标签下,表示一个菜单项,菜单项里面可以嵌套其他的item菜单项。
④.<item>标签的type属性代表了此像的类型,分为seperator和menuitem两类,前者对应toolstripitem类,后者对应toolstripseparator类
⑤.<item>标签中,type属性为menuitem时,还可以设置text属性(显示文字)、shortkey属性(快捷键)、functionattribute属性(生成实例后,单击此菜单项需要调用的函数绑定特性值)
另:在本程序中单击生成后的菜单调用的是一个函数,该函数上方有一个remarkattribute特性,functionattribute属性的值如果与之一致则调用该函数。这个特性的设计并不是死的,在本程序中是函数,经过修改后,也可以对应自定义控件、类等。
3.关于程序窗体
程序窗体没有设置其他的属性,只有一个空的menustrip,名为mnsmainmenu。窗体的名称为formmain。
4.程序代码
using system; using system.collections.generic; using system.componentmodel; using system.data; using system.drawing; using system.linq; using system.text; using system.threading.tasks; using system.windows.forms; using system.xml; using system.reflection; namespace program22 { public partial class formmain : form { public formmain() { initializecomponent(); } //1.把menuconfig.xml中的信息反映到菜单mnsmainmenu上 //2.显示文本、快捷键等信息直接添加,functionname属性添加到tag中 //3.通过反射找到对应函数,完成操作 private void form1_load(object sender, eventargs e) { setmainmenu("menuconfig.xml"); } /// <summary> /// 设置menustrip控件 /// </summary> /// <param name="address"></param> private void setmainmenu(string address) { //设置前清空menustrip中所有项 mnsmainmenu.items.clear(); //读取xml文件 xmldocument xmldoc = new xmldocument(); xmldoc.load(address); xmlnode root = xmldoc.selectsinglenode("menustrip"); setmenu(mnsmainmenu, root); } /// <summary> /// 设置menustrip控件第一层菜单及其子菜单 /// </summary> /// <param name="ms">menustrip控件</param> /// <param name="xnode">xml结点</param> private void setmenu(menustrip ms, xmlnode xnode) { foreach (xmlnode xn in xnode.childnodes) { xmlelement xe = (xmlelement)xn; toolstripmenuitem newtsmi = new toolstripmenuitem(xe.getattribute("text")); //设置快捷键 if (string.isnullorwhitespace(xe.getattribute("shortkey"))) { setshortkey(newtsmi, xe.getattribute("shortkey")); } //设置调用函数 if (!string.isnullorwhitespace(xe.getattribute("functionattribute"))) { newtsmi.tag = xe.getattribute("functionattribute"); newtsmi.click += toolstripmenuitem_click; } //设置子菜单 if (xn.childnodes.count != 0) { setitem(newtsmi, xn); } ms.items.add(newtsmi); } } /// <summary> /// 设置 toolstripmenuitem 控件及其子菜单(递归设置) /// </summary> /// <param name="tsmi">toolstripmenuitem控件</param> /// <param name="xnode">xml结点</param> private void setitem(toolstripmenuitem tsmi, xmlnode xnode) { foreach (xmlnode xn in xnode.childnodes) { xmlelement xe = (xmlelement)xn; toolstripmenuitem newtsmi = new toolstripmenuitem(xe.getattribute("text")); switch (xe.getattribute("type")) { case "menuitem": { //设置快捷键 if (!string.isnullorwhitespace(xe.getattribute("shortkey"))) { setshortkey(newtsmi, xe.getattribute("shortkey")); } //设置调用函数 if (!string.isnullorwhitespace( xe.getattribute("functionattribute"))) { newtsmi.tag = xe.getattribute("functionattribute"); newtsmi.click += toolstripmenuitem_click; } //设置子菜单 if (xn.childnodes.count != 0) { setitem(newtsmi, xn); } tsmi.dropdownitems.add(newtsmi as toolstripitem); } break; case "seperator": { tsmi.dropdownitems.add(new toolstripseparator()); } break; default: break; } } } /// <summary> /// 通过字符串(如"ctrl+alt+a")判断按键信息 /// </summary> /// <param name="key"></param> /// <returns></returns> private void setshortkey(toolstripmenuitem tsmi, string key) { system.windows.forms.keys result = default(system.windows.forms.keys); string[] keys = key.split('+'); if (keys.contains("ctrl")) { result |= keys.control; } if (keys.contains("shift")) { result |= keys.shift; } if (keys.contains("alt")) { result |= keys.alt; } if (keys.contains("a")) { result |= keys.a; } if (keys.contains("b")) { result |= keys.b; } if (keys.contains("c")) { result |= keys.c; } if (keys.contains("d")) { result |= keys.d; } if (keys.contains("e")) { result |= keys.e; } if (keys.contains("f")) { result |= keys.f; } if (keys.contains("g")) { result |= keys.g; } if (keys.contains("h")) { result |= keys.h; } if (keys.contains("i")) { result |= keys.i; } if (keys.contains("j")) { result |= keys.j; } if (keys.contains("k")) { result |= keys.k; } if (keys.contains("l")) { result |= keys.l; } if (keys.contains("m")) { result |= keys.m; } if (keys.contains("n")) { result |= keys.n; } if (keys.contains("o")) { result |= keys.o; } if (keys.contains("p")) { result |= keys.p; } if (keys.contains("q")) { result |= keys.q; } if (keys.contains("r")) { result |= keys.r; } if (keys.contains("s")) { result |= keys.s; } if (keys.contains("t")) { result |= keys.t; } if (keys.contains("u")) { result |= keys.u; } if (keys.contains("v")) { result |= keys.v; } if (keys.contains("w")) { result |= keys.w; } if (keys.contains("x")) { result |= keys.x; } if (keys.contains("y")) { result |= keys.y; } if (keys.contains("z")) { result |= keys.z; } if (keys.contains("0")) { result |= keys.d0; } if (keys.contains("1")) { result |= keys.d1; } if (keys.contains("2")) { result |= keys.d2; } if (keys.contains("3")) { result |= keys.d3; } if (keys.contains("4")) { result |= keys.d4; } if (keys.contains("5")) { result |= keys.d5; } if (keys.contains("6")) { result |= keys.d6; } if (keys.contains("7")) { result |= keys.d7; } if (keys.contains("8")) { result |= keys.d8; } if (keys.contains("9")) { result |= keys.d9; } if (keys.contains("f1")) { result |= keys.f1; } if (keys.contains("f2")) { result |= keys.f2; } if (keys.contains("f3")) { result |= keys.f3; } if (keys.contains("f4")) { result |= keys.f4; } if (keys.contains("f5")) { result |= keys.f5; } if (keys.contains("f6")) { result |= keys.f6; } if (keys.contains("f7")) { result |= keys.f7; } if (keys.contains("f8")) { result |= keys.f8; } if (keys.contains("f9")) { result |= keys.f9; } if (keys.contains("f10")) { result |= keys.f10; } if (keys.contains("f11")) { result |= keys.f11; } if (keys.contains("f12")) { result |= keys.f12; } tsmi.shortcutkeys = result; } /// <summary> /// 特性 remarkattribute,用在函数上,其 remark 属性决定了 /// 积分函数 integration 应该选择程序中的哪个函数进行计算 /// </summary> [attributeusage(attributetargets.method)] public class remarkattribute : attribute { string remark; public string remark { get { return remark; } } //构造函数 public remarkattribute(string comment) { remark = comment; } } /// <summary> /// 单击一个toolstripmenuitem后触发的事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void toolstripmenuitem_click(object sender, eventargs e) { //如果tag为空,则不执行任何事件 if (string.isnullorwhitespace((string)((toolstripmenuitem)sender).tag)) { return; } //如果tag存在,则寻找具有和tag内容一致特性的函数并调用 functioninvoke((string)((toolstripmenuitem)sender).tag); } /// <summary> /// 调用具有指定特性名的函数 /// </summary> /// <param name="funcattr">函数的remarkattribute特性值</param> private void functioninvoke(string funcattr) { //需要 using system.reflection; methodinfo[] mi = typeof(formmain).getmethods( bindingflags.public | bindingflags.nonpublic | bindingflags.instance); //找到具有指定特性的函数,进行调用 foreach (methodinfo m in mi) { type t2 = typeof(remarkattribute); remarkattribute ra = (remarkattribute)attribute.getcustomattribute(m, t2); if (ra != null && ra.remark == funcattr) { m.invoke(this, new object[] { }); break; } } } //需要调用的函数 [remarkattribute("colortored")] //窗口底色:红 private void changecolortored() { this.backcolor = color.red; } [remarkattribute("colortolawngreen")] //窗口底色:绿 private void changecolortolawngreen() { this.backcolor = color.lawngreen; } [remarkattribute("formnormal")] //窗口大小:普通 private void changesizetonrm() { this.windowstate = formwindowstate.normal; } [remarkattribute("formminimize")] //窗口大小:最小化 private void changesizetomin() { this.windowstate = formwindowstate.minimized; } [remarkattribute("formmaximize")] //窗口大小:最大化 private void changesizetomax() { this.windowstate = formwindowstate.maximized; } [remarkattribute("formclose")] //退出程序 private void closeform() { application.exit(); } [remarkattribute("formabout")] //关于程序 private void aboutform() { messagebox.show("write by tsybius 2014/5/15"); } } }
希望本文所述对大家的c#程序设计有所帮助。
上一篇: 详谈PHP编码转换问题
推荐阅读