zoukankan      html  css  js  c++  java
  • C# 利用xml动态生成带图标菜单

    这几天想用vs2005做点东西。要用到windows form 的MainMenu控件。于是想做成动态生成并且动态梆定事件,在网上找了一下没有发现什么好的方法。于是自己来研究一下。以前是做web form的东西,对windows form还真有点陌生的感觉。还好以前用Delphi也做过类似人功能有一点印象。就是用递归去创建菜单。好了不多说了,下面看代码。


            
    ******* void frmMain_Load(object sender, EventArgs e)
            
    {
                CreateMenu();
            }


            
    /// <summary>
            
    /// 动态创建菜单
            
    /// </summary>

            ******* void CreateMenu()
            
    {
                
    //定义一个主菜单
                MenuStrip mainMenu = new MenuStrip();
                DataSet ds 
    = new DataSet();
                
    //从XML中读取数据。数据结构后面详细讲一下。
                ds.ReadXml(@"..\..\Menu.xml");
                DataView dv 
    = ds.Tables[0].DefaultView;
                
    //通过DataView来过滤数据首先得到最顶层的菜单
                dv.RowFilter = "ParentItemID=0";
                
    for(int i=0; i<dv.Count;i++)
                
    {
                    
    //创建一个菜单项
                    ToolStripMenuItem topMenu = new ToolStripMenuItem();
                    
    //给菜单赋Text值。也就是在界面上看到的值。
                    topMenu.Text = dv[i]["Text"].ToString();
                    
    //如果是有下级菜单则通过CreateSubMenu方法来创建下级菜单
                    if (Convert.ToInt16(dv[i]["IsModule"]) == 1)
                    
    {
                        
    //以ref的方式将顶层菜单传递参数,因为他可以在赋值后再回传。--也许还有更好的方法^_^.
                        CreateSubMenu(ref topMenu, Convert.ToInt32(dv[i]["ItemID"]),ds.Tables[0]);
                    }

                    
    //显示应用程序中已打开的 MDI 子窗体列表的菜单项
                    mainMenu.MdiWindowListItem = topMenu;
                    
    //将递归附加好的菜单加到菜单根项上。
                    mainMenu.Items.Add(topMenu);
                }

                mainMenu.Dock 
    = DockStyle.Top;
                
    //将窗体的MainMenuStrip梆定为mainMenu.
                this.MainMenuStrip = mainMenu;
                
    //这句很重要。如果不写这句菜单将不会出现在主窗体中。
                this.Controls.Add(mainMenu);
            }


            
    /// <summary>
            
    /// 创建子菜单
            
    /// </summary>
            
    /// <param name="topMenu">父菜单项</param>
            
    /// <param name="ItemID">父菜单的ID</param>
            
    /// <param name="dt">所有菜单数据集</param>

            ******* void CreateSubMenu(ref ToolStripMenuItem topMenu,int ItemID, DataTable dt)
            
    {
                DataView dv 
    = new DataView(dt);
                
    //过滤出当前父菜单下在所有子菜单数据(仅为下一层的)
                dv.RowFilter = "ParentItemID=" + ItemID.ToString();
                
                
    for (int i = 0; i < dv.Count; i++)
                
    {
                    
    //创建子菜单项
                    ToolStripMenuItem subMenu = new ToolStripMenuItem();
                    subMenu.Text 
    = dv[i]["Text"].ToString();
                    
    //如果还有子菜单则继续递归加载。
                    if (Convert.ToInt16(dv[i]["IsModule"]) == 1)
                    
    {
                        
    //递归调用
                        CreateSubMenu(ref subMenu, Convert.ToInt32(dv[i]["ItemID"]), dt);
                    }

                    
    else
                    
    {
                        
    //扩展属性可以加任何想要的值。这里用formName属性来加载窗体。
                        subMenu.Tag = dv[i]["FormName"].ToString();
                        
    //给没有子菜单的菜单项加事件。
                        subMenu.Click += new EventHandler(subMenu_Click);
                    }

                    
    if (dv[i]["ImageName"].ToString().Length > 0)
                    
    {
                        
    //设置菜单项前面的图票为16X16的图片文件。
                        Image img = Image.FromFile(@"..\..\Image\"+dv[i]["ImageName"].ToString());
                        subMenu.Image 
    = img;
                        subMenu.Image.Tag 
    = dv[i]["ImageName"].ToString();
                    }

                    
    //将菜单加到顶层菜单下。
                    topMenu.DropDownItems.Add(subMenu);
                }

            }


            
    /// <summary>
            
    /// 菜单单击事件
            
    /// </summary>
            
    /// <param name="sender"></param>
            
    /// <param name="e"></param>

            void subMenu_Click(object sender, EventArgs e)
            
    {
                
    //tag属性在这里有用到。
                string formName = ((ToolStripMenuItem)sender).Tag.ToString();
                CreateFormInstance(formName);
            }


            
    /// <summary>
            
    /// 创建form实例。
            
    /// </summary>
            
    /// <param name="formName">form的类名</param>

            ******* void CreateFormInstance(string formName)
            
    {
                
    bool flag = false;
                
    //遍历主窗口上的所有子菜单
                for(int i=0;i<this.MdiChildren.Length; i++)
                
    {
                    
    //如果所点的窗口被打开则重新激活
                    if (this.MdiChildren[i].Tag.ToString().ToLower() == formName.ToLower())
                    
    {
                        
    this.MdiChildren[i].Activate();
                        
    this.MdiChildren[i].Show();
                        
    this.MdiChildren[i].WindowState = FormWindowState.Normal;
                        flag 
    = true;
                        
    break;
                    }

                }

                
    if (!flag)
                
    {
                    
    //如果不存在则用反射创建form窗体实例。
                    Assembly asm = Assembly.Load("Fastyou.BookShop.Win");//程序集名
                    object frmObj = asm.CreateInstance("Fastyou.BookShop.Win." + formName);//程序集+form的类名。
                    Form frms = (Form)frmObj;
                    
    //tag属性要重新写一次,否则在第二次的时候取不到。原因还不清楚。有知道的望告知。
                    frms.Tag = formName.ToString();
                    frms.MdiParent 
    = this;
                    frms.Show();
                }

            }
    <?xml version="1.0" encoding="utf-8" ?>
    <Menus>
        
    <MenuItem>
            
    <Text>资料管理</Text>
            
    <ItemID>1000</ItemID>
            
    <ParentItemID>0</ParentItemID>
            
    <FormName></FormName>
            
    <IsModule>1</IsModule>
            
    <Level>1</Level>
            
    <ImageName>01.bmp</ImageName>
        
    </MenuItem>
        
    <MenuItem>
            
    <Text>产品管理</Text>
            
    <ItemID>1100</ItemID>
            
    <ParentItemID>0</ParentItemID>
            
    <FormName></FormName>
            
    <IsModule>1</IsModule>
            
    <Level>1</Level>
            
    <ImageName>16x16_ico_pdf.gif</ImageName>        
        
    </MenuItem>
        
    <MenuItem>
            
    <Text>进书管理</Text>
            
    <ItemID>100001</ItemID>
            
    <ParentItemID>1000</ParentItemID>
            
    <FormName>frmInputBooks</FormName>
            
    <IsModule>0</IsModule>
            
    <Level>2</Level>
            
    <ImageName>crest16x16.gif</ImageName>
        
    </MenuItem>
        
    <MenuItem>
            
    <Text>买卖管理</Text>
            
    <ItemID>100002</ItemID>
            
    <ParentItemID>1000</ParentItemID>
            
    <FormName></FormName>
            
    <IsModule>1</IsModule>
            
    <Level>2</Level>
            
    <ImageName>ico16-16.gif</ImageName>
        
    </MenuItem>
        
    <MenuItem>
            
    <Text>作业管理</Text>
            
    <ItemID>110001</ItemID>
            
    <ParentItemID>1100</ParentItemID>
            
    <FormName></FormName>
            
    <IsModule>1</IsModule>
            
    <Level>2</Level>
            
    <ImageName>ico_info_16x16_mask.gif</ImageName>
        
    </MenuItem>
        
    <MenuItem>
            
    <Text>买书管理</Text>
            
    <ItemID>10000201</ItemID>
            
    <ParentItemID>100002</ParentItemID>
            
    <FormName></FormName>
            
    <IsModule>1</IsModule>
            
    <Level>3</Level>
            
    <ImageName>ico_tmn_16x16.jpg</ImageName>
        
    </MenuItem>
        
    <MenuItem>
            
    <Text>买sss管理</Text>
            
    <ItemID>1000020101</ItemID>
            
    <ParentItemID>10000201</ParentItemID>
            
    <FormName>frmBuyBook</FormName>
            
    <IsModule>0</IsModule>
            
    <Level>4</Level>
            
    <ImageName>ico16-16.gif</ImageName>
        
    </MenuItem>
        
    <MenuItem>
            
    <Text>dsafasdf</Text>
            
    <ItemID>11000101</ItemID>
            
    <ParentItemID>110001</ParentItemID>
            
    <FormName>frmBuyBook</FormName>
            
    <IsModule>0</IsModule>
            
    <Level>3</Level>
            
    <ImageName>ico16-16.gif</ImageName>
        
    </MenuItem>
    </Menus>

    下面来说明一下XML文件。
    Text:为显示在窗体上的文字,
    ItemID:为菜单的ID,
    ParentItemID:为此菜单的父菜单ID如果是顶级菜单则为0
    FormName:为单击菜单所要显示的窗体类名如果是还有下级菜单的则不要写。
    IsModule:是否还有子菜单1有,0没有
    Level:菜单所在的层数。目前还没用到。
    ImageName:菜单前的图标为16x16的图片文件。
    在这里还可以根据自己的需要加其它的属性,也可以写成以数据库的方式。
    这是我目前用到的功能。我会继续发表我做这个小软件的心得体会。希望对大家有所帮助。

  • 相关阅读:
    无线安全
    下载安装Emacs和基本配置--待更新中
    uv-pv-vv的区别
    tesseract安装及问题处理
    POJ 2187 Beauty Contest【凸包周长】
    POJ 1113 Wall【凸包周长】
    POJ 2187 Beauty Contest【旋转卡壳求凸包直径】
    POJ 2031 Building a Space Station【经典最小生成树】
    URAL 1181 Cutting a Painted Polygon【递归+分治】
    POJ 1845-Sumdiv【经典数学题目---求因子和】
  • 原文地址:https://www.cnblogs.com/hackpig/p/1668408.html
Copyright © 2011-2022 走看看