2. Revit API UI 之 IExternalCommand 和 IExternalApplication
上一篇我们大致看了下 RevitAPI 的一级命名空间划分,再简单讲了一下Attributes
命名空间下的3个类,并从一个代码样例,提到了Attributes
和IExternalCommand
,前者是指示外部命令要满足的要求或要执行的动作,后者呢,就是外部命令接口。和外部命令接口类似的接口,还有IExternalApplication
(外部应用)和IExternalEventHandler
(外部事件)
这一篇呢,如题目所说,讲的是UI
命名空间的部分,讲其中的IExternalCommand
和IExternalApplication
这两个接口
Revit UI Namespace
在讲外部命令和外部事件之前,我们得先了解一下UI命名空间下,都有哪些东西。
我在这儿贴了一个图,该导图使用FreeMind制作。
注:图中
未
包含Autodesk.Revit.UI
下的所有成员
IExternalCommand 外部命令
当一个类实现了IExternalCommand
接口,就可以通过官方插件Addin Manager
加载运行测试。该插件可以在安装的 Revit SDK 目录下找到,具体就不多介绍了。
接口实现
IExternalCommand 接口需要实现一个Execute
方法,该方法传入了3个参数:
commandData
:包含应用程序、视图、日志映射的引用,这些是外部命令所需的;message
:如果命令失败,可以返回错误消息,这个字符串有1023个字符的限制;elements
:如果命令失败,可以指示问题元素的集合。
先看个示例代码,作用是删除项目中的所有元素。
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIApplication uiApp = commandData.Application; // 拿到当前活跃着的会话
UIDocument uiDoc = uiApp.ActiveUIDocument; // 拿到UI交互相关的引用
Document doc = uiDoc.Document; // 拿到文档引用,操作一般都在这个上面
// 启动一个事务,删除文档中的元素。
// 不要忘记了上一篇的TransactionAttribute
using (Transaction transaction = new Transaction(doc, "delete all element"))
{
try
{
transaction.Start(); // 开始事务
FilteredElementCollector collector = new FilteredElementCollector(doc);
IList<Element> elementsToDelete = collector.ToElements();
foreach (Element element in elementsToDelete)
{
doc.Delete(element.Id);
}
transaction.Commit(); // 提交事务
}
catch (Exception ex)
{
transaction.RollBack(); // 回滚事务
message = ex.Message;
return Result.Failed;⌈⌋
}
}
return Result.Succeeded;
}
好了,这个接口的使用就是这么的简单。
IExternalApplication 外部应用
同样的,实现IExternalApplication
接口,再通过.addin
配置文件进行注册,就可以愉快得使用啦。
与外部命令不同的,是外部应用要实现的不在是⌈执行⌋方法,而是OnStartup
和OnShutdown
。
接口实现
OnStartup 方法会在Revit启动时调用,允许开发者执行初始化任务,比如添加界面、设置事件处理器等。
OnShutdown 就是在Revit关闭时调用。一般用于行清理工作,比如注销事件处理器、保存设置、释放资源等。
看一个例子,Revit启动的时候,在Revit最顶栏加一个叫“测试Tab”的选项,内部就一个叫“Panel”的面板,面板里就一个“Bottun”按钮。
还有呢,会启动一个空闲事件,作用是Revit有空的时候就打印一下。
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
using Nice3point.Revit.Toolkit.External; // 一个三方库,封装了IExternalApplication接口
// 基本没区别,需要实现的方法没参数了
namespace RevitDuctLoad
{
[UsedImplicitly]
public class Application : ExternalApplication
{
public override void OnStartup()
{
this.CreateRibbon(this.Application); // 创建按钮
this.Application.Idling += new EventHandler<IdlingEventArgs>(this.IdlingHandler); // 开启空闲事件
}
public override void OnShutdown()
{
this.Application.Idling -= new EventHandler<IdlingEventArgs>(this.IdlingHandler); // 关闭空闲事件
}
private void IdlingHandler(object sender, IdlingEventArgs e)
{
TaskDialog.Show("提示", $"空闲事件:{DateTime.Now.ToString("mm:ss")}");
}
private void CreateRibbon(UIControlledApplication application)
{
string tabName = "测试Tab";
application.CreateRibbonTab(tabName); // 再
RibbonPanel panel = application.CreateRibbonPanel(tabName, "Panel");
PushButton button = panel.AddItem(new PushButtonData("Bottun", "Bottun", AddInPath, "XXX.TestCommand")) as PushButton;
button.ToolTip = "这是一个测试按钮,执行测试命令";
}
}
}
结尾
就一丢丢内容,也没什么好说的。
这一节我们提到了Document
,UIDocument
,Transaction
(事务),还有 Ribbon
(界面相关)和 Idling
(空闲事件),这些我们后面讲。
噢,还提到了一个同样是“外部”东西 IExternalEventHandler
,这个要到再后面一些了。
下一篇南北,讲一下 Dialog
相关的内容,比较简单,就先写了。