在winform中根据数据库信息动态生成菜单

往往直接根据数据库的信息生成的菜单没有分类性,如果我们事前设定好一个xml结构,然后数据库信息匹配该结构生成需要的菜单,这样是不是更灵活、更好呢。呵呵。代码如下。

using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Text;
using  System.Windows.Forms;
using  System.Xml;
using  System.IO;
namespace  CreateMenuByXMLFromList
{
    
public partial class Form2 : Form
    
{
        
public Form2()
        
{
            InitializeComponent();
        }

        
        
private List<string> GetDbMenuList()
        
{
            List
<string> dbMenuList = new List<string>();
            dbMenuList.Add(
"进书管理");
            dbMenuList.Add(
"买卖管理");
            dbMenuList.Add(
"作业管理");
            dbMenuList.Add(
"买书管理");
            dbMenuList.Add(
"买sss管理");

            
return dbMenuList;
        }


        
/// <summary>
        
/// 将目录链表与目录结构xml文件进行匹配生成新的xml文件
        
/// </summary>
        
/// <param name="menuFilepath">目录结构xml文件</param>
        
/// <param name="dbMenuList">目录链表</param>

        private void createUserMenuXmlFile(string structureFilepath, string menuFilepath, List<string> dbMenuList)
        
{
            XmlDocument xmlUserMenu 
= new XmlDocument();
            xmlUserMenu.LoadXml(
"<Menu></Menu>");

            XmlDocument xmlMenu 
= new XmlDocument();
            xmlMenu.Load(structureFilepath);
//@"....menu.xml"
            XmlNodeList xmlMenuList = xmlMenu.GetElementsByTagName("MenuItem");

            
for (int i = 0; i < xmlMenuList.Count; i++)
            
{
                
for (int j = 0; j < dbMenuList.Count; j++)
                
{
                    
if (xmlMenuList.Item(i)["Text"].InnerText == dbMenuList[j])
                    
{
                        XmlNode newMenu 
= xmlUserMenu.ImportNode(xmlMenuList.Item(i), true);
                        xmlUserMenu.DocumentElement.AppendChild(newMenu);
                    }

                }

            }


            XmlDeclaration xmldecl 
= xmlUserMenu.CreateXmlDeclaration("1.0""utf-8"null);
            
//Add the new node to the document.
            XmlElement root = xmlUserMenu.DocumentElement;
            xmlUserMenu.InsertBefore(xmldecl, root);

            
try
            
{
                xmlUserMenu.Save(menuFilepath);
            }

            
catch
            
{
                
throw;
            }

        }


        
        
private List<string> GetUserListFromDbMenuList(List<string> dbMenuList)
        
{
            List
<string> userList = new List<string>();

            
for (int i = 0; i < dbMenuList.Count; i++)
            
{
                List
<string> parentList = new List<string>();
                GetTheParentsList(
ref parentList, dbMenuList[i]);
                
//GetTheParentsList(ref parentList, dbMenuList[1]);
                userList.AddRange(parentList);
            }


            removeRepeatItems(
ref userList);

            
return userList;
        }


        
/// <summary>
        
/// 去除链表中的多于元素
        
/// </summary>
        
/// <param name="userList"></param>

        private void removeRepeatItems(ref List<string> userList)
        
{
            
for (int j = 0; j < userList.Count; j++)
            
{
                
for (int i = 0; i < userList.Count; i++)
                
{
                    
if (userList[i] == userList[j] && i != j)
                    
{
                        userList.RemoveAt(i);
                        i
--;
                    }

                }

            }


        }


        
/// <summary>
        
/// 根据孩子节点创建家族集合链表
        
/// </summary>
        
/// <param name="menuList"></param>
        
/// <param name="childNode"></param>

        private void GetTheParentsList(ref List<string> menuList, string childNode)
        
{
            List
<string> parentList = new List<string>();
            parentList.Add(childNode);
            
if (hasParent(childNode))
            
{
                
string parentNode = GetParentNode(childNode);
                GetTheParentsList(
ref parentList, parentNode);
                menuList.AddRange(parentList);
            }

            
else
            
{
                menuList.Add(childNode);
            }

        }


        
private string GetParentNode(string childNode)
        
{
            
string parentName = string.Empty;
            
string parentID = string.Empty;

            XmlDocument xmlMenu 
= new XmlDocument();
            xmlMenu.Load(
@"....menu.xml");
            XmlNodeList xmlMenuList 
= xmlMenu.GetElementsByTagName("MenuItem");
            
for (int i = 0; i < xmlMenuList.Count; i++)
            
{
                
if (childNode == xmlMenuList[i]["Text"].InnerText)
                
{
                    parentID 
= xmlMenuList[i]["ParentItemID"].InnerText;
                    
break;
                }

            }

            
for (int i = 0; i < xmlMenuList.Count; i++)
            
{
                
if (parentID == xmlMenuList[i]["ItemID"].InnerText)
                
{
                    parentName 
= xmlMenuList[i]["Text"].InnerText;
                    
break;
                }

            }

            

            
return parentName;
        }


        
private bool hasParent(string childNode)
        
{
            
bool hasParent = false;

            XmlDocument xmlMenu 
= new XmlDocument();
            xmlMenu.Load(
@"....menu.xml");
            XmlNodeList xmlMenuList 
= xmlMenu.GetElementsByTagName("MenuItem");
            
for (int i = 0; i < xmlMenuList.Count; i++)
            
{
                
if (childNode == xmlMenuList[i]["Text"].InnerText)
                
{
                    
if (xmlMenuList[i]["ParentItemID"].InnerText != "0")
                    
{
                        hasParent 
= true;
                        
break;
                    }

                }

            }


            
return hasParent;
        }


        
private void Form2_Load(object sender, EventArgs e)
        
{
            List
<string> dbMenuList = GetDbMenuList();
            List
<string> userMenuList = GetUserListFromDbMenuList(dbMenuList);

            createUserMenuXmlFile(
@"....menu.xml"@"userMenu.xml", userMenuList);

            CreateMenu(
@"userMenu.xml");

            File.Delete(Directory.GetCurrentDirectory() 
+ "/userMenu.xml");
            
        }



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

        private void CreateMenu(string menuFilepath)
        
{
            
//定义一个主菜单
            MenuStrip mainMenu = new MenuStrip();
            DataSet ds 
= new DataSet();
            
//从XML中读取数据。数据结构后面详细讲一下。
            ds.ReadXml(menuFilepath);
            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>

        private 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(@"...." + 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);
            MessageBox.Show("aaa");
        }


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

        private 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();
            
//}
        }

    }

}

 menu.xml文件

<? xml version="1.0" encoding="utf-8"  ?>
< Menus >
  
< MenuItem >
    
< Text > 资料管理 </ Text >
    
< ItemID > 1 </ ItemID >
    
< ParentItemID > 0 </ ParentItemID >
    
< IsModule > 1 </ IsModule >
    
< name > DataManage </ name >
    
< ImageName > 01.bmp </ ImageName >
  
</ MenuItem >
  
< MenuItem >
    
< Text > 产品管理 </ Text >
    
< ItemID > 2 </ ItemID >
    
< ParentItemID > 0 </ ParentItemID >
    
< IsModule > 1 </ IsModule >
    
< name > ProductManage </ name >
    
< ImageName > 01.bmp </ ImageName >
  
</ MenuItem >
  
< MenuItem >
    
< Text > 进书管理 </ Text >
    
< ItemID > 3 </ ItemID >
    
< ParentItemID > 1 </ ParentItemID >
    
< IsModule > 0 </ IsModule >
    
< name > StockManage </ name >
    
< ImageName > 01.bmp </ ImageName >
  
</ MenuItem >
  
< MenuItem >
    
< Text > 买卖管理 </ Text >
    
< ItemID > 4 </ ItemID >
    
< ParentItemID > 1 </ ParentItemID >
    
< IsModule > 1 </ IsModule >
    
< name > TradeManage </ name >
    
< ImageName > 01.bmp </ ImageName >
  
</ MenuItem >
  
< MenuItem >
    
< Text > 作业管理 </ Text >
    
< ItemID > 5 </ ItemID >
    
< ParentItemID > 2 </ ParentItemID >
    
< IsModule > 0 </ IsModule >
    
< name > WorkManage </ name >
    
< ImageName > 01.bmp </ ImageName >
  
</ MenuItem >
  
< MenuItem >
    
< Text > 买书管理 </ Text >
    
< ItemID > 6 </ ItemID >
    
< ParentItemID > 4 </ ParentItemID >
    
< IsModule > 1 </ IsModule >
    
< name > BuyBookManage </ name >
    
< ImageName > 01.bmp </ ImageName >
  
</ MenuItem >
  
< MenuItem >
    
< Text > 买sss管理 </ Text >
    
< ItemID > 7 </ ItemID >
    
< ParentItemID > 6 </ ParentItemID >
    
< name > BuySssManage </ name >
    
< IsModule > 0 </ IsModule >
  
</ MenuItem >
  
< MenuItem >
    
< Text > dsafasdf </ Text >
    
< ItemID > 8 </ ItemID >
    
< ParentItemID > 5 </ ParentItemID >
    
< IsModule > 0 </ IsModule >
    
< name > dsafasdf </ name >
    
< ImageName > 01.bmp </ ImageName >
  
</ MenuItem >
</ Menus >
中间用到的根据xml生成菜单的方法出自 http://www.cnblogs.com/laihua/archive/2006/08/15/477815.html
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值