文档章节

C#实现用XML配置MenuStrip菜单

北风其凉
 北风其凉
发布于 2014/05/15 16:33
字数 1509
阅读 223
收藏 0

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>

 

配置规则:

1.所有的内容都在标签<MenuStrip>中

2.每一个<Menu>标签代表了一个横向的菜单项,其中Text属性是显示的文字,ShortKey属性是选择用的快捷键

3.每一个<Item>标签都在<Menu>或<Item>标签下,表示一个菜单项,菜单项里面可以嵌套其他的Item菜单项。

4.<Item>标签的Type属性代表了此像的类型,分为Seperator和MenuItem两类,前者对应ToolStripItem类,后者对应ToolStripSeparator类

5.<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"); }
    }
}

END

© 著作权归作者所有

北风其凉

北风其凉

粉丝 119
博文 498
码字总数 463468
作品 4
朝阳
程序员
私信 提问
C#实例:5个.net经典例子(窗体与界面设计)

C#实例:5个.net经典例子(窗体与界面设计) 实例001 带历史信息的菜单 实例说明 在开发图纸管理软件时,要求在菜单上记录用户最近打开的档案或图纸,以方便下次使用。如图1.1所示,单击“文...

庸人谷
2012/11/12
1K
2
C# menuStrip设置带有复选框的按钮

自己写了一个小例子,在menuStrip菜单栏中设置带有复选框的按钮,实现工具栏和状态栏的显示和隐藏。【工具栏和状态栏按钮默认是被选中的,即显示】 1、设置界面 2、属性设置 将【工具栏】和【...

strawberry_ahh
2018/01/05
0
0
获取MDI窗体中控件坐标的方法/屏幕局部截图原位写入

一、程序介绍: 在有MDI窗体的工具条和菜单栏,并且窗体在任何大小时,要想准确获得窗体中控件的坐标,可以使用下列代码: 这段代码的大体含义是在原来的窗体上的pbImg(pictureBox)位置进行...

技术小胖子
2017/11/10
0
0
图像处理控件ImageGear for .NET教程:C# WPF应用程序创建示例(2)

在前面的《图像处理控件ImageGear for .NET教程: C# WPF应用程序创建示例(1)》一文中已经讲解了如何在ImageGear for .NET 中对于C# WPF应用程序创建了项目,本文将继续前文。 设计窗体 一...

愤怒的outman
2013/09/16
337
0
在Winform中菜单动态添加“最近使用文件”

最近在做文件处理系统中,要把最近打开文件显示出来,方便用户使用。网上资料有说,去遍历“C:Documents and SettingsAdministratorRecent”下的最近文档本。文主要介绍在Winform界面菜单中实...

永恒921
2018/12/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
13分钟前
0
0
数据库中间件MyCat

什么是MyCat? 查看官网的介绍是这样说的 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务、ACID、可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵...

沉浮_
今天
4
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
今天
6
0
常用物流快递单号查询接口种类及对接方法

目前快递查询接口有两种方式可以对接,一是和顺丰、圆通、中通、天天、韵达、德邦这些快递公司一一对接接口,二是和快递鸟这样第三方集成接口一次性对接多家常用快递。第一种耗费时间长,但是...

程序的小猿
今天
4
0
Python机器学习之数据探索可视化库yellowbrick

背景介绍 从学sklearn时,除了算法的坎要过,还得学习matplotlib可视化,对我的实践应用而言,可视化更重要一些,然而matplotlib的易用性和美观性确实不敢恭维。陆续使用过plotly、seaborn,...

yeayee
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部