• 一个简单的基于XML的模块集成框架(含SourceCode)


    1. 准备一个xml文件

    xmlmenu

    2.准备一个xml schemal文件来验证xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- edited with XMLSpy v2006 sp2 U (http://www.altova.com) by peter (hust) -->
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
        
    <xs:element name="Menu">
            
    <xs:complexType>
                
    <xs:sequence>
                    
    <xs:element ref="MenuItem" maxOccurs="unbounded"/>
                
    </xs:sequence>
            
    </xs:complexType>
        
    </xs:element>
        
    <xs:element name="MenuItem">
            
    <xs:complexType>
                
    <xs:sequence>
                    
    <xs:element ref="MenuItem" minOccurs="0" maxOccurs="unbounded"/>
                
    </xs:sequence>
                
    <xs:attribute name="AddToolButton">
                    
    <xs:simpleType>
                        
    <xs:restriction base="xs:string">
                            
    <xs:enumeration value="TRUE"/>
                            
    <xs:enumeration value="FALSE"/>
                        
    </xs:restriction>
                    
    </xs:simpleType>
                
    </xs:attribute>
                
    <xs:attribute name="AddToolbar">
                    
    <xs:simpleType>
                        
    <xs:restriction base="xs:string">
                            
    <xs:enumeration value="TRUE"/>
                            
    <xs:enumeration value="FALSE"/>
                        
    </xs:restriction>
                    
    </xs:simpleType>
                
    </xs:attribute>
                
    <xs:attribute name="AssemblyName" type="xs:string" use="required"/>
                
    <xs:attribute name="FormTag" use="required">
                    
    <xs:simpleType>
                        
    <xs:restriction base="xs:string">
                            
    <xs:enumeration value="TRUE"/>
                            
    <xs:enumeration value="FALSE"/>
                        
    </xs:restriction>
                    
    </xs:simpleType>
                
    </xs:attribute>
                
    <xs:attribute name="Image" type="xs:string"/>
                
    <xs:attribute name="Name" type="xs:string" use="required"/>
                
    <xs:attribute name="ShortCut" use="optional">
                    
    <xs:simpleType>
                        
    <xs:restriction base="xs:string">
                            
    <xs:enumeration value="F1"/>
                            
    <xs:enumeration value="F2"/>
                            
    <xs:enumeration value="F3"/>
                            
    <xs:enumeration value="F4"/>
                            
    <xs:enumeration value="F5"/>
                            
    <xs:enumeration value="F6"/>
                            
    <xs:enumeration value="F7"/>
                            
    <xs:enumeration value="F8"/>
                            
    <xs:enumeration value="F9"/>
                            
    <xs:enumeration value="F10"/>
                            
    <xs:enumeration value="F11"/>
                            
    <xs:enumeration value="F12"/>
                            
    <xs:enumeration value="Alt0"/>
                            
    <xs:enumeration value="Alt1"/>
                            
    <xs:enumeration value="Alt2"/>
                            
    <xs:enumeration value="Alt3"/>
                            
    <xs:enumeration value="Alt4"/>
                            
    <xs:enumeration value="Alt5"/>
                            
    <xs:enumeration value="Alt6"/>
                            
    <xs:enumeration value="Alt7"/>
                            
    <xs:enumeration value="Alt8"/>
                            
    <xs:enumeration value="Alt9"/>
                            
    <xs:enumeration value="AltBksp"/>
                            
    <xs:enumeration value="AltF1"/>
                            
    <xs:enumeration value="AltF2"/>
                            
    <xs:enumeration value="AltF3"/>
                            
    <xs:enumeration value="AltF4"/>
                            
    <xs:enumeration value="AltF5"/>
                            
    <xs:enumeration value="AltF6"/>
                            
    <xs:enumeration value="AltF7"/>
                            
    <xs:enumeration value="AltF8"/>
                            
    <xs:enumeration value="AltF9"/>
                            
    <xs:enumeration value="AltF10"/>
                            
    <xs:enumeration value="AltF11"/>
                            
    <xs:enumeration value="AltF12"/>
                            
    <xs:enumeration value="AltDownArrow"/>
                            
    <xs:enumeration value="AltUpArrow"/>
                            
    <xs:enumeration value="AltLeftArrow"/>
                            
    <xs:enumeration value="AltRightArrow"/>
                            
    <xs:enumeration value="Ctrl0"/>
                            
    <xs:enumeration value="Ctrl1"/>
                            
    <xs:enumeration value="Ctrl2"/>
                            
    <xs:enumeration value="Ctrl3"/>
                            
    <xs:enumeration value="Ctrl4"/>
                            
    <xs:enumeration value="Ctrl5"/>
                            
    <xs:enumeration value="Ctrl6"/>
                            
    <xs:enumeration value="Ctrl7"/>
                            
    <xs:enumeration value="Ctrl8"/>
                            
    <xs:enumeration value="Ctrl9"/>
                            
    <xs:enumeration value="CtrlA"/>
                            
    <xs:enumeration value="CtrlB"/>
                            
    <xs:enumeration value="CtrlC"/>
                            
    <xs:enumeration value="CtrlD"/>
                            
    <xs:enumeration value="CtrlE"/>
                            
    <xs:enumeration value="CtrlF"/>
                            
    <xs:enumeration value="CtrlG"/>
                            
    <xs:enumeration value="CtrlH"/>
                            
    <xs:enumeration value="CtrlI"/>
                            
    <xs:enumeration value="CtrlJ"/>
                            
    <xs:enumeration value="CtrlK"/>
                            
    <xs:enumeration value="CtrlL"/>
                            
    <xs:enumeration value="CtrlM"/>
                            
    <xs:enumeration value="CtrlN"/>
                            
    <xs:enumeration value="CtrlO"/>
                            
    <xs:enumeration value="CtrlP"/>
                            
    <xs:enumeration value="CtrlQ"/>
                            
    <xs:enumeration value="CtrlR"/>
                            
    <xs:enumeration value="CtrlS"/>
                            
    <xs:enumeration value="CtrlT"/>
                            
    <xs:enumeration value="CtrlU"/>
                            
    <xs:enumeration value="CtrlV"/>
                            
    <xs:enumeration value="CtrlX"/>
                            
    <xs:enumeration value="CtrlY"/>
                            
    <xs:enumeration value="CtrlZ"/>
                            
    <xs:enumeration value="CtrlF1"/>
                            
    <xs:enumeration value="CtrlF2"/>
                            
    <xs:enumeration value="CtrlF3"/>
                            
    <xs:enumeration value="CtrlF4"/>
                            
    <xs:enumeration value="CtrlF5"/>
                            
    <xs:enumeration value="CtrlF6"/>
                            
    <xs:enumeration value="CtrlF7"/>
                            
    <xs:enumeration value="CtrlF8"/>
                            
    <xs:enumeration value="CtrlF9"/>
                            
    <xs:enumeration value="CtrlF10"/>
                            
    <xs:enumeration value="CtrlF11"/>
                            
    <xs:enumeration value="CtrlF12"/>
                            
    <xs:enumeration value="CtrlIns"/>
                            
    <xs:enumeration value="CtrlShift0"/>
                            
    <xs:enumeration value="CtrlShift1"/>
                            
    <xs:enumeration value="CtrlShift2"/>
                            
    <xs:enumeration value="CtrlShift3"/>
                            
    <xs:enumeration value="CtrlShift4"/>
                            
    <xs:enumeration value="CtrlShift5"/>
                            
    <xs:enumeration value="CtrlShift6"/>
                            
    <xs:enumeration value="CtrlShift7"/>
                            
    <xs:enumeration value="CtrlShift8"/>
                            
    <xs:enumeration value="CtrlShift9"/>
                            
    <xs:enumeration value="CtrlShiftA"/>
                            
    <xs:enumeration value="CtrlShiftB"/>
                            
    <xs:enumeration value="CtrlShiftC"/>
                            
    <xs:enumeration value="CtrlShiftD"/>
                            
    <xs:enumeration value="CtrlShiftE"/>
                            
    <xs:enumeration value="CtrlShiftF"/>
                            
    <xs:enumeration value="CtrlShiftG"/>
                            
    <xs:enumeration value="CtrlShiftH"/>
                            
    <xs:enumeration value="CtrlShiftI"/>
                            
    <xs:enumeration value="CtrlShiftJ"/>
                            
    <xs:enumeration value="CtrlShiftK"/>
                            
    <xs:enumeration value="CtrlShiftL"/>
                            
    <xs:enumeration value="CtrlShiftM"/>
                            
    <xs:enumeration value="CtrlShiftN"/>
                            
    <xs:enumeration value="CtrlShiftO"/>
                            
    <xs:enumeration value="CtrlShiftP"/>
                            
    <xs:enumeration value="CtrlShiftQ"/>
                            
    <xs:enumeration value="CtrlShiftR"/>
                            
    <xs:enumeration value="CtrlShiftS"/>
                            
    <xs:enumeration value="CtrlShiftT"/>
                            
    <xs:enumeration value="CtrlShiftU"/>
                            
    <xs:enumeration value="CtrlShiftV"/>
                            
    <xs:enumeration value="CtrlShiftW"/>
                            
    <xs:enumeration value="CtrlShiftX"/>
                            
    <xs:enumeration value="CtrlShiftY"/>
                            
    <xs:enumeration value="CtrlShiftZ"/>
                            
    <xs:enumeration value="ShiftIns"/>
                            
    <xs:enumeration value="ShiftF1"/>
                            
    <xs:enumeration value="ShiftF2"/>
                            
    <xs:enumeration value="ShiftF3"/>
                            
    <xs:enumeration value="ShiftF4"/>
                            
    <xs:enumeration value="ShiftF5"/>
                            
    <xs:enumeration value="ShiftF6"/>
                            
    <xs:enumeration value="ShiftF7"/>
                            
    <xs:enumeration value="ShiftF8"/>
                            
    <xs:enumeration value="ShiftF9"/>
                            
    <xs:enumeration value="ShiftF10"/>
                            
    <xs:enumeration value="ShiftF11"/>
                            
    <xs:enumeration value="ShiftF12"/>
                            
    <xs:enumeration value=""/>
                        
    </xs:restriction>
                    
    </xs:simpleType>
                
    </xs:attribute>
            
    </xs:complexType>
        
    </xs:element>
    </xs:schema>

    3。定义一个类来加载菜单

    public class MenuLoad
        
    {
            
    private PluginCollection m_plugins = null;
            
    public MenuBar _menbar = new MenuBar();
            
    public ToolStrip _toolbar = new ToolStrip();
            
    private OutlookBar bar = new OutlookBar();
            
    private ImageList imglist = new ImageList();
            
    private StringBuilder builder = new StringBuilder();

            
    public MenuLoad()
            
    {
                bar 
    = _menbar.outlookBar;
            }


            
    private TabControl tabCtrl;
            
    public TabControl TabCtrl
            
    {
                
    set
                
    {
                    tabCtrl 
    = value;
                }

            }


            
    private void ValidationEventHandler(object sender, ValidationEventArgs e)
            
    {
                builder.AppendLine(
    "验证XML文档的时候发生错误:");
                builder.AppendLine(
    "严重级别:" + e.Severity);
                builder.AppendLine(
    "错误信息:" + e.Message);
                builder.AppendLine(
    "------+--------+-------+------+--------+-------+------+--------+-------+");
                builder.AppendLine();
            }


            
    /// <summary>
            
    /// 验证XML文件是否是合乎规范的文件
            
    /// </summary>
            
    /// <param name="xmlfile">文件名称</param>
            
    /// <returns>是则返回true,否则返回false</returns>

            private bool ValidateXml(string xmlfile)
            
    {
                
    bool validXml = false;
                
    string spath = "";

                spath 
    = Application.StartupPath + "\\configurations\\XMLSMenu.xsd";
                
    if(!System.IO.File.Exists(spath))
                
    {
                    
    throw new System.IO.FileNotFoundException(String.Format(Resources.StringFileNotFound, spath));
                }


                XmlReaderSettings settings 
    = new XmlReaderSettings();
                XmlSchemaSet schemaSet 
    = new XmlSchemaSet();
                schemaSet.Add(
    null, spath);
                settings.Schemas.Add(schemaSet);
                settings.ValidationType 
    = ValidationType.Schema;
                settings.ValidationEventHandler 
    += new ValidationEventHandler(ValidationEventHandler);
                settings.ValidationFlags 
    = settings.ValidationFlags | XmlSchemaValidationFlags.ReportValidationWarnings;

                XmlReader reader 
    = XmlReader.Create(xmlfile, settings);


                
    while(reader.Read())
                
    {

                }

                
                
    if(builder.Length > 0)
                
    {
                    validXml 
    = false;
                }

                
    else
                
    {
                    validXml 
    = true;
                }

                reader.Close();
                
    return validXml;

            }

            
    /// <summary>
            
    /// 加载菜单
            
    /// </summary>
            
    /// <param name="main">主菜单</param>
            
    /// <param name="xmlfile">菜单定义文件</param>

            public MainMenu LoadMenus(string xmlfile)
            
    {
                MainMenu mainmenu 
    = new MainMenu();
                
                
    try
                
    {
                    
    using(new WaitCursor())
                    
    {
                        
    //验证XML是否是合乎规范的XML文件
                        if(ValidateXml(xmlfile))
                        
    {
                            XmlDocument document 
    = new XmlDocument();
                            document.Load(xmlfile);

                            XmlNode rootNode 
    = document.DocumentElement;
                            mainmenu 
    = GetMenus(rootNode);   
                        }

                        
    else
                        
    {
                            
    throw new Exception(builder.ToString());
                        }

                    }

                }

                
    catch (System.IO.FileNotFoundException)
                
    {
                    Utility.ShowErrorMsg(String.Format(Resources.StringFileNotFound, xmlfile));
                }


                
    return mainmenu;
            }


            
    /// <summary>
            
    /// 加载菜单
            
    /// </summary>
            
    /// <param name="main">主菜单</param>
            
    /// <param name="node">菜单项节点</param>

            private MainMenu GetMenus(XmlNode node)
            
    {
                MainMenu mainmenu 
    = new MainMenu();
                List
    <XmlNode> nodelist= new List<XmlNode>();
                List
    <OfficeMenuItem> mnulist = new List<OfficeMenuItem>();
                List
    <IconPanel> iplist = new List<IconPanel>();
                
    string menutext ="";
                
    //首先加载主菜单,避免迭代的时候菜单显示的过分延迟。
                foreach(XmlNode child in node.ChildNodes)
                
    {
                    
    if(child.NodeType == XmlNodeType.Element && child.Name == "MenuItem")
                    
    {
                        menutext 
    = child.Attributes["Name"].Value;
                        OfficeMenuItem item 
    = new OfficeMenuItem(true,menutext);
                        mainmenu.MenuItems.Add(item);
                        IconPanel cp 
    = new IconPanel();
                        bar.AddBand(menutext, cp);
                        nodelist.Add(child);
                        mnulist.Add(item);
                        iplist.Add(cp);
                    }

                }

                
    //加载所有的子菜单
                GetSubMenus(iplist.ToArray(),mnulist.ToArray(), nodelist.ToArray());
                
    return mainmenu;
            }


            
    /// <summary>
            
    /// 加载所有子菜单
            
    /// </summary>
            
    /// <param name="main">主菜单集合</param>
            
    /// <param name="node">菜单节点集合</param>

            private void GetSubMenus(IconPanel[] iplist ,OfficeMenuItem[] main, XmlNode[] node)
            
    {
                EventHandler handler 
    = new EventHandler(OnPluginClick);
                EventHandler handler1 
    = new EventHandler(OnIconClick);
                EventHandler handler2 
    = new EventHandler(OnButtonClick);
                
    string asmname;
                
    string formtag;
                
    string text;
                MenuClass mc;
                XmlNode child;
                
    string iconpath = "";
                
    string iconname = "";
                
    string msc = "";
                
    for(int i = 0; i <= main.GetUpperBound(0); i++)
                
    {
                    
    //foreach(XmlNode child in node[i].ChildNodes)
                    for(int j = 0; j < node[i].ChildNodes.Count;j++ )
                    
    {
                        child 
    = node[i].ChildNodes[j];
                        
    if(child.NodeType == XmlNodeType.Element && child.Name == "MenuItem")
                        
    {
                            asmname 
    = child.Attributes["AssemblyName"].Value;
                            formtag 
    = child.Attributes["FormTag"].Value;
                            text 
    = child.Attributes["Name"].Value;
                            msc 
    = child.Attributes["ShortCut"].Value;
                            OfficeMenuItem item 
    = new OfficeMenuItem(true, text, handler);
                            iconname 
    = child.Attributes["Image"].Value;
                            
    if(iconname != string.Empty)
                            
    {
                                iconpath 
    = Themes.GetCurrentThemePath() +iconname;
                                item.IconPath 
    = iconpath;
                                
                            }
     
                            mc 
    = new MenuClass();
                            mc.Assemblyname 
    = asmname;
                            mc.FormTag 
    = formtag;

                            item.Tag 
    = mc;

                            
    if(msc != string.Empty)
                            
    {
                                item.Shortcut 
    = MenuShortCut.GetShortCut(msc);
                            }


                            main[i].MenuItems.Add(item);

                            
    if((iconpath != string.Empty) && System.IO.File.Exists(iconpath))
                            
    {    //添加按钮到OutlookBar                        
                                PanelIcon picon = iplist[i].AddIcon(item.Text,Image.FromFile(iconpath),handler1);
                                picon.Tag 
    = mc;
                                
    //添加按钮到toolbar
                                ToolStripButton button = new ToolStripButton(item.Text, Image.FromFile(iconpath), handler2);
                                button.DisplayStyle 
    = ToolStripItemDisplayStyle.Image;
                                button.ToolTipText 
    = item.Text;
                                button.Tag 
    = mc;
                                button.Visible 
    = true;
                                _toolbar.Items.Add(button);
                            }


                            iconpath 
    = "";
                            mc 
    = null;

                            
    if(child.ChildNodes.Count > 0)
                            
    {
                                GetChildMenu(iplist[i],item, child);
                            }

                        }

                    }

                    
    //添加分割线
                    ToolStripSeparator ss = new ToolStripSeparator();
                    _toolbar.Items.Add(ss);
                }

            }


            
    /// <summary>
            
    /// 加载子菜单
            
    /// </summary>
            
    /// <param name="parent">父菜单</param>
            
    /// <param name="node">父菜单定义XML节点</param>

            private void GetChildMenu(IconPanel ip,OfficeMenuItem parent, XmlNode node)
            
    {
                EventHandler handler 
    = new EventHandler(OnPluginClick);
                EventHandler handler1 
    = new EventHandler(OnIconClick);
                EventHandler handler2 
    = new EventHandler(OnButtonClick);

                MenuClass mc;
                
    string asmname;
                
    string formtag;
                
    string text;
                XmlNode child1;
                
    string iconpath = "";
                
    string iconname = "";
                
    string msc = "";
                
    //foreach(XmlNode child1 in node.ChildNodes)
                for(int i = 0; i < node.ChildNodes.Count - 1;i++ )
                
    {
                    child1 
    = node.ChildNodes[i];
                    
    //检查是否提供了类型
                    asmname = child1.Attributes["AssemblyName"].Value;
                    formtag 
    = child1.Attributes["FormTag"].Value;
                    text 
    = child1.Attributes["Name"].Value;
                    OfficeMenuItem childitem;

                    childitem 
    = new OfficeMenuItem(true, text, handler);
                    childitem.Name 
    = text;
                    mc 
    = new MenuClass();
                    mc.Assemblyname 
    = asmname;
                    mc.FormTag 
    = formtag;
                    
                    childitem.Tag 
    = mc;
                    
    //添加快捷键
                    msc = child1.Attributes["ShortCut"].Value;
                    
    if(msc != string.Empty)
                    
    {
                        childitem.Shortcut 
    = MenuShortCut.GetShortCut(msc);
                    }

                    
    //添加图标
                    iconname = child1.Attributes["Image"].Value;
                    
    if(iconname != string.Empty)
                    
    {
                        iconpath 
    = Themes.GetCurrentThemePath() + iconname;
                        childitem.IconPath 
    = iconpath;
                    }
     

                    parent.MenuItems.Add(childitem);

                    
    if((iconpath != string.Empty) && System.IO.File.Exists(iconpath))
                    
    {    //添加按钮到OutlookBar                        
                        PanelIcon picon = ip.AddIcon(childitem.Text, Image.FromFile(iconpath), handler1);
                        picon.Tag 
    = mc;
                        
    //添加按钮到toolbar
                        ToolStripButton button = new ToolStripButton(childitem.Text, Image.FromFile(iconpath), handler2);
                        button.DisplayStyle 
    = ToolStripItemDisplayStyle.Image;
                        button.ToolTipText 
    = childitem.Text;
                        button.Tag 
    = mc;
                        button.Visible 
    = true;
                        _toolbar.Items.Add(button);
                    }


                    iconpath 
    = "";
                    mc 
    = null;

                    
    if(child1.ChildNodes.Count > 0)
                    
    {
                        GetChildMenu(ip,childitem, child1);
                    }

                }

            }


            
    /// <summary>
            
    /// 打开一个窗体
            
    /// </summary>
            
    /// <param name="asmname">窗体类程序集和窗体类的组合,从节点的AssemblyName属性获取</param>

            private  void OpenForm(MenuClass mc)
            
    {
                
    string asmname = mc.Assemblyname;
                
    string formtag = mc.FormTag;

                
    if (formtag == "")
                
    {
                    
    throw new Exception(Resources.StringNoFormFlag);
                }


                
    if(formtag.ToUpper() == "TRUE")
                
    {
                    
    if(asmname == string.Empty)
                    
    {
                        
    throw new NullReferenceException(Resources.StringAssemblyNull);
                    }



                    
    //string[] a = asmname.Split(',');
                    object obj = null;
                    Type tp 
    = Type.GetType(asmname);
                    
    if(tp != null)
                    
    {
                        obj 
    = Activator.CreateInstance(tp);
                    }

                    
    else
                    
    {
                        
    throw new Exception("加载程序的时候出错,请检查程序(dll,exe)是否存在或者类型是否正确。");
                    }



                    
    //检查是否是Form类
                    if((obj == null| !(obj is Form))
                    
    {
                        
    throw new Exception(Resources.StringNotForm);
                    }


                    Form frm 
    = (obj as Form);

                    
    //检查打开的第一个窗口是否是MDIFORM
                    if(Application.OpenForms[0].IsMdiContainer)
                    
    {
                        
    //作为MDICHILDFORM
                        frm.MdiParent = Application.OpenForms[0];
                    }

                    
    //加载窗体
                    frm.Show();


                }

            }


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

            private void OnPluginClick(object sender, EventArgs args)
            
    {
                OfficeMenuItem item 
    = (OfficeMenuItem)sender;
                MenuClass mc 
    = (MenuClass) item.Tag;
                
    if ((item.Text == "退出"| (item.Text == "EXIT"))
                
    {
                    OnExitClick(sender, args);
                    
    return;
                }

                OpenForm(mc);
            }


        }

    这里面用到了delegate,最重要的函数是加载菜单的函数和OnPluginClick函数。

    使用这个框架可以动态增加任意的层次的模块。

    微软的CAB 使用Resigster site方式来增加模块,感觉不是很方便。
  • 相关阅读:
    最小的K个数
    数组中出现次数超过一半的数字
    合并排序
    一只小蜜蜂...
    从零开始学springboot笔记(三)-Spring boot之热部署之Springloaded(仅做了解,实际开发中不用它)
    从零开始学springboot笔记(二)-Spring boot返回json数据(中文无乱码)
    从零开始学springboot笔记(一)-Spring boot之Hello Word
    IDEA2018永久破解版下载与安装
    $.ajaxSettings.async = false;是什么意思?
    嘿嘿
  • 原文地址:https://www.cnblogs.com/yanrongpi/p/372378.html
Copyright © 2020-2023  润新知