http://monodevelop.com/Developers/Articles/The_Command_System#Menus_and_Toolbars
命令系统
本文阐述了Monodevelop命令系统的工作机制以及开发者如何利用这些优势来写自己的插件。
1。基本概念
在阐述Monodevelop命令系统的工作机制之前,我们先要了解两件事
命令和使用这些命令的菜单和工具条是分开定义的
命令的执行是取决于上下文的,比如说你在文本编辑器中调用delete和在工程目录树中调用delete虽然都
是同一条命令,但是执行结果却是不一样的。
2。命令定义
命令都是要定义在"/MonoDevelop/Ide/Commands" 这个扩展点下面,如下:
defaultHandler = " MonoDevelop.Ide.Commands.RunHandler "
icon = " gtk-execute "
shortcut = " F5 "
description = " Run "
_label = " Run " />
id:命令的标识,注意:这个id一定要和已存在的枚举类型的全名(包括命名空间)保持一致。这个枚举
类型会被用来确定执行那个具体的命令。
defaultHandler:是用来标识执行当前上下文中默认的命令类
icon:在工具条和菜单栏中显示的图标
_lable: 在菜单栏上显示的文本
description:显示在tooltip上的文字(可选)
shortcut: 命令的快捷键
Toggle 命令
是用来在主文本旁边显示一个是否触发状态的命令,以及显示工具栏是否激活的标识。这些命令用check
来标识。如下:
type = " check "
_label = " Build " />
如果有多个toggle命令相互排斥,那么你可以用radio类型来标识。
Custom commands 自定义命令
自定义命令用来展示在菜单和工具栏上的自定义的小窗体。如果要使用它,先将type属性设置为custom然
后在widget标签中指定相应的小窗体类。如下:
type = " custom "
widget = " MonoDevelop.Ide.Gui.ConfigurationComboBox "
_label = " Active Configuration " />
Command Arrays 命令组
命令组是用来实现菜单栏中的选择列表。
defaultHandler = " MonoDevelop.Ide.Commands.OpenWindowListHandler "
type = " radio|array "
_label = " Window List " />
注意:array和check可以同时使用,也可以和radio一起使用。一般来说,命令组用来动态的在菜单和工
具栏上产生命令。
defaultHandler = " MonoDevelop.Ide.Commands.RecentFileListHandler "
type = " array "
_label = " Recent Files " />
3。菜单和工具条
Menus and Toolbars 菜单栏和工具条
菜单栏和工具条用相同的方式来定义。IDE提供了很多扩展点来定义主菜单,主工具条,如下:
CommandItem
Creates an item that will invoke the command identified by the id attribute. If the command
is actually a command array, it will create an item for each element in the command array.
SeparatorItem
ItemSet
创建一个item的字项菜单,它有两个属性_label和icon
用在工具栏上,那就是下拉式的
LinkItem
创建打开网络连接的入口
Creates a menu or toolbar entry that opens a web page in the default web browser. For
example:
4。执行命令
执行命令
牢记:命令的执行和命令的上下文息息相关
那什么是上下文呢?上下文就是拥有焦点的窗体,当焦点改变的时候,上下文也随之而变。命令集就跟着
变为可用或者不可用。
这意味这我们每一个窗体定义命令执行类了吗?非也,每个widget都有一个command dispathcroute.dang
当调用一个命令的时候,如果具有焦点的widget没有handler,那么它就会传递给route上的下一个对象,
也就是父widget
如下图所示:
通常,command routes会按照下面这个顺序来寻找:
*拥有焦点的widget
*父widget,直到root widget
*全局command Handler,使用这个来注册:Ide.CommandServices.RegisterGlobalHandler(object)
*default handler:就是配置文件中的defaulterHandler
Implementing command handlers实现
protected void OnSaveFile ()
{
// Do the save
}
FileCommands.Save是用来标记命令的枚举值
Managing Command Status 更改命令状态
打开monodevelop,新建一个文件,发现delete是禁用的,输入一些字,发现它可用用了,点一些任务列
表,发现它又不可以用了。这是怎么做到的呢?
我们先要理解一件事:命令系统会自动禁用不是该command route上的命令.这是在焦点发生改变的时候发
生的。
如果命令的状态依附于应用内部的逻辑结构,可用将它加入到一个特殊的Command Update Handler。
protected void OnUpdateSaveFile (CommandInfo info)
{
IViewContent content = window.ActiveViewContent as IViewContent;
info.Enabled = content.IsDirty;
}
这条命令会在命令系统想要知道命令的状态的时候调用。比如说菜单命令,当菜单要显示的时候就调用,
工具栏是周期性的调用。
因为命令更新和命令是一体的,所以更新的方法要和执行的方法在一起写。
在command update handler 中,你可以使用commandinfo对象来改变对象的状态。但并不限于此,你可以
改变command的所有属性,比如说描述文字,可见性等等。
Array command handlers
The default command handler
Startup Extension Path
这个特殊的commandhandler会在monodevelop启动的时候调用的,你需要做两件事。
首先,将你的class 比如说myhandler加入到启动的扩展点,修改MonoDevelop.Ide.addin.xml 文件像这
样:
< Class class = " MyHandler " />
</ Extension >
接下来,完成这个类的实现
{
protected override void Run ()
{
Console.Out.WriteLine("Hello World!");
}
}