OSGI(五)界面插件制作1

来源:互联网 发布:javaweb课程设计源码 编辑:程序博客网 时间:2024/04/29 16:53
                

                 通过之前的介绍大家都知道我们可以做好插件,直接在界面调用即可;那么我们界面插件如何读取其他插件的信息并生成相应的菜单呢?下面开始介绍:

 

                  我们通过一个现有的简单winform的界面插件来学习界面插件如何制作。首先创建一个高级windows窗体主应用程序。



              运行程序,在插件仓库中下载该插件——简单winform通用窗体插件;安装成功之后运行。效果如下:



    大家可以看到该程序有一些菜单,这些菜单都是一个个的插件,那么咱们的这个程序是如何将插件加载进来的呢?这是咱们主要要学习的地方,把加载机制学会了,以后才能即使用自己的界面又能用灵活的插件。

        下面咱们分析一下,上篇博客中说了,是通过Manifest文件加载的菜单;主要是解析了Extension point节点下的Application;我们来看看如何做到解析Manifest文件。该源码可从官网上下载。


1.创建拓展模型

        这个界面框架通过OSGi.NET的扩展点-扩展机制实现了界面的扩展,允许其它插件通过定义扩展的方式将界面元素注册到该界面框架。这个框架接受的扩展配置如下所示。扩展点名称为UIShell.Applications,底下是Application和Menu定义。Application对应于界面菜单的根节点,Menu表示这个插件的所有菜单配置,支持嵌套方式。每个Menu可以定义一个Class属性,表示点击这个菜单时,在内容区域显示的窗体或者用户控件全名称。


2.创建拓展模型对象

       现在定义相应的拓展对象,看源码ExtensionModel目录下有3个文件,WinShellApplicationWinShellMenu对应Extension信息里面的ApplicationMenuXML节点配置,WinShellApplicationContainerWinShellApplication对象容器。下面我们看一下:

WinShellApplicationContainer核心代码如下:

1)将一个扩展转换成WinShellApplication对象,并添加到缓存,然后返回该对象 :

         /// <summary>        /// 将一个扩展转换成WinShellApplication对象。        /// </summary>        /// <param name="extension">指定的扩展对象。</param>        /// <returns>返回的WinShellApplication对象。</returns>        public WinShellApplication AddApplicationForExtension(Extension extension)        {            WinShellApplication app = null;            List<XmlNode> data = extension.Data;            if (data != null && data.Count > 0)            {                // 1 将扩展的Application XML节点转换成WinShellApplication对象。                XmlNode topNode = data[0];                if (topNode.NodeType == XmlNodeType.Element && topNode.Attributes != null && topNode.Attributes["Title"] != null)                {                    string appTitle = topNode.Attributes["Title"].Value;                    string appToolTip = topNode.Attributes["ToolTip"].Value;                    string appIcon = topNode.Attributes["Icon"].Value;                    if (!string.IsNullOrEmpty(appTitle))                    {                        string parentGuid = Guid.NewGuid().ToString();                        int topNodeLevel = 0;                        app = new WinShellApplication(appTitle, appToolTip, appIcon, extension.Owner);                        // 2 递归的将扩展的Menu XML节点及其子节点转换成WinShellMenu对象。                        CreateWinShellMenusFromXmlNode(app.Menus, app, null, topNode, topNodeLevel);                        // 3 将Application对象保存起来。                        _instance.AddApplication(app);                    }                }            }            return app;        }        
2)删除Extension对应的WinShellApplication对象:

         /// <summary>        /// 删除Extension对应的WinShellApplication。        /// </summary>        /// <param name="extension">指定的Extension。</param>        /// <returns>删除的WinShellApplication对象。</returns>        public WinShellApplication RemoveApplicationForExtension(Extension extension)        {            var app = GetWinShellApplication(extension.Owner);            if (app != null)            {                RemoveApplication(app);            }            return app;        }

3获取一个插件注册的扩展信息对应的WinShellApplication对象:

 

         /// <summary>        /// 获取指定插件的WinShellApplication对象。        /// </summary>        /// <param name="bundle">指定插件。</param>        /// <returns>WinShellApplication对象。</returns>        public WinShellApplication GetWinShellApplication(IBundle bundle)        {            foreach (WinShellApplication app in Applications)            {                if (app.Bundle.Equals(bundle))                    return app;            }            return null;        }
4获取一个插件注册的扩展信息对应的一级菜单列表:

         /// <summary>        /// 获取指定插件的顶层菜单对象。        /// </summary>        /// <param name="bundle">指定插件。</param>        /// <returns>顶层菜单对象集合。</returns>        public List<WinShellMenu> GetTopWinShellMenus(IBundle bundle)        {            WinShellApplication app = GetWinShellApplication(bundle);            if (app != null)                return app.Menus;            return null;        }

5)将扩展的Menu对应的XML节点解析成WinShellMenu对象集合:

 

         /// <summary>        /// 将扩展的Menu对应的XML节点解析成WinShellMenu集合。        /// </summary>        /// <param name="menus">顶层WinShellMenu集合。</param>        /// <param name="application">所属的WinShellApplication。</param>        /// <param name="parent">父菜单。</param>        /// <param name="topNode">顶层XML节点。</param>        /// <param name="nodeLevel">XML节点层次。</param>        private void CreateWinShellMenusFromXmlNode(List<WinShellMenu> menus, WinShellApplication application, WinShellMenu parent, XmlNode topNode, int nodeLevel)        {            if (menus == null)            {                menus = new List<WinShellMenu>();            }            foreach (XmlNode childNode in topNode.ChildNodes)            {                if (childNode.NodeType == XmlNodeType.Element)                {                    string type = null;                    if (childNode.Attributes["Class"] != null)                        type = childNode.Attributes["Class"].Value;                    string text = childNode.Attributes["Text"] == null ? string.Empty : childNode.Attributes["Text"].Value;                    string toolTip = childNode.Attributes["ToolTip"] == null ? string.Empty : childNode.Attributes["ToolTip"].Value;                    string icon = childNode.Attributes["Icon"] == null ? string.Empty : childNode.Attributes["Icon"].Value;                    string guid = Guid.NewGuid().ToString();                    // 创建WinShellMenu对象。                    WinShellMenu winShellMenu = new WinShellMenu(application, parent, text, toolTip, icon, type, nodeLevel, guid);                    menus.Add(winShellMenu);                    // 递归创建子节点对象。                    int childNodeLevel = nodeLevel + 1;                    CreateWinShellMenusFromXmlNode(winShellMenu.Children, application, winShellMenu, childNode, childNodeLevel);                }            }        }

         WinShellApplication类对应扩展的ApplicationXML节点,其Title、ToolTip、Icon属性对应XML相应属性,Bundle表示定义这个节点的插件,Menus表示子菜单集合。

           WinShellMenu类对应扩展的MenuXML,其Text、ToolTip、Icon属性对应相应XML属性,ClassName对应Class属性,Application表示所属的WinShellApplication对象,Parent表示父菜单对象,Children表示子菜单对象列表。

建立扩展模型后,我们接着要来创建一个主界面了。

          现在我们把用到的基础类讲解了,下篇博客中我们来看看到底如何设计插件界面的界面,敬请期待。。。










0 0