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#程序设计有所帮助。
相关文章
- 我们在使用C#做项目的时候,基本上都需要制作登录界面,那么今天我们就来一步步看看,如果简单的实现登录界面呢,本文给出2个例子,由简入难,希望大家能够喜欢。...2020-06-25
- 这篇文章主要介绍了C# 字段和属性的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下...2020-11-03
- 这篇文章主要介绍了C#中截取字符串的的基本方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-03
- 这篇文章主要介绍了C#实现简单的Http请求的方法,以实例形式较为详细的分析了C#实现Http请求的具体方法,需要的朋友可以参考下...2020-06-25
- 本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
- 本文主要介绍了C#中new的几种用法,具有很好的参考价值,下面跟着小编一起来看下吧...2020-06-25
使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)
这篇文章主要介绍了使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25- 这篇文章主要介绍了C#开发Windows窗体应用程序的简单操作步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
- 这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
- 最近做一个小项目不可避免的需要前端脚本与后台进行交互。由于是在asp.net中实现,故问题演化成asp.net中jiavascript与后台c#如何进行交互。...2020-06-25
- 本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
- 轻松学习C#的基础入门,了解C#最基本的知识点,C#是一种简洁的,类型安全的一种完全面向对象的开发语言,是Microsoft专门基于.NET Framework平台开发的而量身定做的高级程序设计语言,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C#变量命名规则小结,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-09
- 这篇文章主要介绍了C#绘制曲线图的方法,以完整实例形式较为详细的分析了C#进行曲线绘制的具体步骤与相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
- 这篇文章主要介绍了c#自带缓存使用方法,包括获取数据缓存、设置数据缓存、移除指定数据缓存等方法,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了c#中(&&,||)与(&,|)的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
- 这篇文章主要用实例讲解C#递归算法的概念以及用法,文中代码非常详细,帮助大家更好的参考和学习,感兴趣的朋友可以了解下...2020-06-25
- 下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
- 这篇文章主要介绍了C#中list用法,结合实例形式分析了C#中list排序、运算、转换等常见操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25