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个文件,WinShellApplication和WinShellMenu对应Extension信息里面的Application和MenuXML节点配置,WinShellApplicationContainer是WinShellApplication对象容器。下面我们看一下:
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表示子菜单对象列表。
建立扩展模型后,我们接着要来创建一个主界面了。
现在我们把用到的基础类讲解了,下篇博客中我们来看看到底如何设计插件界面的界面,敬请期待。。。
- OSGI(五)界面插件制作1
- OSGI(六)界面插件制作2
- unity 编辑器和插件制作(五)
- QT学习(五)----360界面制作(2终结)
- Eclipse插件开发之基础篇(5) 制作OSGi Bundle
- Eclipse插件开发之基础篇(5) 制作OSGi Bundle
- Eclipse插件开发之基础篇(5) 制作OSGi Bundle
- 使用python制作ArcGIS插件(4)界面交互
- 四、界面制作(1)
- 使用 Equinox 开发 OSGi 应用程序(五)
- OSGi介绍(五)两个bundle
- osgi 学习系列(五)spring dm
- OSGI Eclipse 插件使用OSGI
- 我也来玩OSGI(五)
- OSGi 插件管理
- Eclipse插件Osgi
- 自己的osgi收藏(比较详尽的osgi学习文档)五与hibernate的集成
- Karaf OSGi && JavaEE 通俗易懂版 实战教程入门(五)
- hdu 4027
- Qt中 QObject类干了什么事情
- dojo之FilteringSelect
- Oracle创建用户、表空间、导入导出、...命令
- jsp
- OSGI(五)界面插件制作1
- Unity3d中UnityEngine.Object的几个注意点
- ansi、Unicode、Utf-8之间的转化
- Unity3d-在Unity项目中使用Mono DLL(动态链接库)
- 赵青-《剑侠情缘网络版》开发回顾
- servlet (3) 对象
- Django1.6.2 自带服务器admin不能加载CSS
- 1.Go by Example: Hello World
- hibernate-get和load方法异同