SharpDevelop学习笔记(5)—— AddIns系统详解

  1 关于AddIn 系统文件
本文描述SharpDevelop使用的AddIn系统。如果您打算为SharpDevelop写AddIns,您应该阅读”AddIn建立向导”以学会应该怎样构造您的项目。
本文大体上描述有关SharpDevelop的AddIn系统(ICSharpCode.核心)和一般(或者公共的普通的)子集(或延伸)
2 AddIn
编写AddIns由二个(或更多)文件组成:AddIn xml定义,addin库(.dll、.exe)。
当SharpDevelop开始时所有AddIns的xml都会被读取并将会生成单一的树结构.
AddIn 树是“把他们全部绑在一起"的树。它被构造得像一个文件系统。如果我们想要访问 SubNode2 我们必须像这样 /Path1/SubPath1/Node1/SubNode2.指定出地点.
我们观察到Node1 像一条路径,但是我们随后将看到Path(路径)和Node(节点)之间的区别。暂时,我们且说节点是包含行为定义的路径。
AddIn 树的最普通的用途是用来扩展菜单和工具栏。当SharpDevelop想要新建一个菜单或工具栏时,它会在AddIn树里使用一个特别的路径.路径 “/SharpDevelop/Workbench/MainMenu”包含主菜单的项目,路径”/SharpDevelop/ViewContent/Browser/Toolbar”包含浏览器的工具栏(新网页,帮助浏览器等).
2.1 AddIn 定义
AddIn 树的每个节点有一个Codon(密码子). 在ICSharpCode.Core执行中, AddInTreeNode class有一个Codon特性,即空路径和指向适合于节点的Codon实例.
我们看一个用codon定义一个结点的XML方式:
<MenuItem id       = "Build"
          label    = "${res:XML.MainMenu.BuildMenu.BuildSolution}"
          shortcut = "F8"
          icon     = "Icons.16x16.BuildCombine"
           class = "ICSharpCode.SharpDevelop.Project.Commands.Build"/>  
当AddInTree被加载,一个Codon的事例就建立出来了 。 它命名的特性开始于“MenuItem(菜单项)”,它的ID特性在于“Build”. 其他属性都放在了“Properties”箱里(就像Hsahtable)。Codon 包含了关于菜单项目的信息:标签、捷径、图标和点击项目时运行起来的类的完全授权名称.
有关AddInTree的重要的一点是AddInTree是通过在所有AddIns中结合AddIn定义构建的.举个例子,来自开始页面AddIn的 StartPage.addin 文件包含这些:
<Path name = "/SharpDevelop/Workbench/MainMenu/View">
     <MenuItem id = "ShowStartPage"
               insertafter = "ViewItemsSeparator"
               insertbefore = "FullScreen"
               label = "${res:XML.MainMenu.ViewMenu.ShowStartPage}"
               icon = "Icons.16x16.BrowserWindow"
               class = "ICSharpCode.StartPage.ShowStartPageCommand"/>
</Path>
路径 “/SharpDevelop/Workbench/MainMenu/View” 被定义在两个文件中:位于SharpDevelop中的主要AddIn文件和 StartPage的AddIn文件.当加载文件时, ICSharpCode.Core把路径的内容合并入AddIn树中。 属性insertafter(之后插入)和 insertbefore(之前插入)是专用的,他们通过指定前一个和后一个项目的ID来控制在什么位置插入项目。
2.2 运行时间部分
每个AddIn定义文件有一个AddIn 类的实例。 类包含有在标题中建立的信息和AddIn定义文件的运行时间部分。 在那些文件中每一个为结点创造的Codon类也会给AddIn类的提供一个参考。
AddIn 定义文件的header(标题)包含有以下属性:名字,作者,版权,addin主页的URL,描述以及版本。
Values( 数值)储存在AddIn类的的属性中。
Runtime 的部分如下所示:
<Runtime>
         <Import assembly = "CSharpBinding.dll"/>
         <Import assembly = ":ICSharpCode.SharpDevelop"/>
</Runtime>
输入的元素储存在AddIn类的Runtime属性中。 AddIn类也有一种方法“CreateObject”(新建目标). CreateObject用在应该新建一个菜单项目的类的时候。通常当该项目被第一次点击时CreateObject被要求提供菜单项目. CreateObject将审阅所有输入的 assembly 并且寻找指定的类名(其顺序按照输入内容在Runtime部分被安置的位置来进行)。
当CreateObject首次需要这些输入的 assembly 时这些 assembly 便被加载。这产生的结果就是: 当优先使用它们时,AddIns被随之加载.这对于SharpDevelop的启动时间是一项巨大的改进。
CreateObject 仅在指定的集合里寻找类。当您想要从SharpDevelop的主 assembly 里使用一个类的时候(例如像这样一个普通的命令Undo 等),您也要必须输入那个集合。 当它被多个addin 参考时它不会被加载两次。 因为addins能够在任何的子目录里存在,指定一个固定的路径回到ICSharpCode.SharpDevelop.dll.是不可能的。有一个特殊的方法在主目录里参考集合,可是:当集合属性从冒号开始的话(<Import assembly = ":ICSharpCode.SharpDevelop"/>),  SharpDevelop 会使用“Assembly.Load” 来加载集合而不是普通的 “Assembly.LoadFrom”. 您将不用必须制订回去的路径,但是还有另一个重要区别: 您不使用.dll文件扩展名。
Runtime 的部分可能也包含doozer和条件求值定义,阅读doozer和条件部分以获取更多有关信息。
2.3 Doozers 解析器
现在到问题了:怎么让一个Codon变成一个System.Windows.Forms.MenuStrip Command 在这里doozers开始活动了:Doozers是从codon里 建立项目的帮助类(所有对象都是可能的)。
这里有一个MenuItemDoozer的简化版本:
public class MenuItemDoozer : IDoozer
{
  // More on HandleConditions in the conditions section.
 public bool HandleConditions { get { return true; } }
 
  public object BuildItem ( object caller, Codon codon, ArrayList subItems)
 {
     if ( codon.Properties.Contains("type"))
    type = codon.Properties["type"];
     else
    type = "Command";
     switch ( type) {
    case "Separator" :
        return new MenuSeparator(codon, caller);
    case "CheckBox" :
        return new MenuCheckBox(codon, caller);
    case "Item" :
        return new MenuCommand(codon, caller);
    case "Command" :
        return new MenuCommand(codon, caller);
    case "Menu" :
        return new Menu(codon, caller, subItems);
    case "Builder" :
        return codon.AddIn.CreateObject(codon.Properties["class"]);
    default :
        throw new NotSupportedException(type);
      }
 }
}
“MenuCommand”,“ MenuCheckBox”高于SharpDevelop类里面诸如“MenuStripCommand”等的其他类。当codon作为属性的时候他们采取他们的标签、图标和捷径信息.当点击一个命令时, MenuCommand调用“codon.AddIn.CreateObject()”,把结果投射到ICommand接口并且调用运行方法 .
如何添加custom doozers?
主 doozer全部直接由SharpDevelopMain.cs添加。但倘若您想要在您的AddIn里面创造您自己的doozer呢?
要实现它 ,你只要把你的doozer包含在XML文件的<Runtime> section(<运行 >部分)就可以了 :
<Import assembly = 'MyAddIn.dll'>
    <Doozer name='MyDoozer' class = 'MyAddIn.MyDoozer'/>
</Import>
通常 ,doozer(和输入的集合)在首先使用的时候便被加载了.
2.4 在AddIn 树 里建立项目
这个部分讨论怎么使您的AddIn创造它自己的扩展路径,从而使您的AddIn可以被其他AddIn延伸到。
上下文菜单 :
静态方法MenuService(菜单服务). CreateContextMenu 可以用于新建一个ContextMenuStrip。
listView.ContextMenuStrip = MenuService.CreateContextMenu(this, "/MyAddIn/SomePath/ContextMenu");
在创造的项目和命令上通过“this”作为参量设置访问者或所有者。命令的运行方法是利用owner属性去获得一个目标的参考并通过参量到达CreateContextMenu。在大多事例中它会把所有者和某一接口或者执行“CreateContextMenu”类的类型放在一起。然后它便可以访问公共方法和属性了.
工具栏:
工具栏跟上下文菜单相似。使用 ToolbarService(工具栏服务) CreateToolStrip( 新建工具条)和添加工具条来返回你的用户控制。
toolStrip = ToolbarService.CreateToolStrip(this, "/MyAddIn/SomePath/Toolbar");
toolStrip.GripStyle = ToolStripGripStyle.Hidden;
Controls.Add(toolStrip);
caller/owner( 访问者/所有者)跟上下文菜单工作方式相似.这里有一个浏览器工具栏的“back”命令:
public class GoBack : AbstractCommand {
    public override void Run () {
     (( HtmlViewPane)Owner).WebBrowser.GoBack();
    }
}
您自己的对象:
它跟运用您自己的对象一样简单. 首先,您需要一个为这个要储存在AddIn树里的 对象设立一个普通的(或者共同的)接口.假设您的AddIn执行一些行动并且想让其他AddIn有可能作用于这些行动, 所以我们可以使用这个接口:
public interface IActionNameListener
{
        void DoAction(MyDataClass data);
}
如果您能在.NET 框架或SharpDevelop中找到一个接口,您应该优先选用它而非你自己创建的那个。
如果您要创建您自己的接口,延伸您AddIn可以参考它,这可能在您重新编译您AddIn的时候产生versioning(版本)的问题.
您能访问像这样的项目:
ArrayListlist = AddInTree.BuildItems("/MyAddIn/ActionName", this, false);
foreach (IActionNameListener obj in list) {
     obj.DoAction(data);
}
按照通过类被insertbefore/insertafter 之前插入/之后插入的属性来说明的顺序,您在路径上将会得到所有被定义的类.第二个参量是owner/caller( 所有者/访问者),如同上下文菜单和工具栏。把所有者给doozer,然后doozer能够把它传递到被创建的对象。 当您使用您自己的对象,您能创建您自己的doozer,当然您不用必须这样做。ICSharpCode.Core已经包含了一个 doozer, 它能够通过反射来调用它们的 parameterless 构造器去 创建任意对象的实例
3. 条件
待续.
4. 可利用的Doozers和ConditionEvaluators名单
将在其它文章中给出
 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值