前言

ModelessForm_ExternalEvent,这个例子主要介绍的是 Revit External Event,用来生成非模态对话框。可以理解为,在不打断 Revit 正常操作的情况下,响应用户的请求。

内容

在开始之前,先了解一下 External Event,可以参考官网:External Events
使用 External Event 的基本逻辑:

  1. IExternalEventHandler这个接口来实现一个事件处理的 handler 类;
  2. 用静态方法 ExternalEvent.Create() 创建一个 ExternalEvent
  3. 在这个非模块对话框中需要 Revit 去进行操作的时候,调用 ExternalEvent.Raise()
  4. 在 Revit 空闲的时候,它会调用用户实现的方法 IExternalEventHandler.Execute() 。

IExternalEventHandler

用户实现一个自己的 IExternalEventHandler,这个用户的处理函数,Revit 最终会在空闲的时候调用这个类的 Execute 方法。

public class ExternalEventExample : IExternalEventHandler
{public void Execute(UIApplication app){TaskDialog.Show("External Event", "Click Close to close.");}public string GetName(){return "External Event Example";}
}

ExternalEvent

用静态方法 ExternalEvent.Create() 创建一个 ExternalEvent

public class ExternalEventExampleApp : IExternalApplication
{// ExternalEventExample 是 IExternalEventHandler 的一个实现public static ExternalEventExampleApp thisApp = null;// 非模态对话框的实例private ExternalEventExampleDialog m_MyForm;public Result OnShutdown(UIControlledApplication application){if (m_MyForm != null && m_MyForm.Visible){m_MyForm.Close();}return Result.Succeeded;}public Result OnStartup(UIControlledApplication application){m_MyForm = null;   // 会在用户触发 command 的时候被初始化thisApp = this;  // 记录 revit application instancereturn Result.Succeeded;}//   External command 会调用这个方法public void ShowForm(UIApplication uiapp){// 如果对话框还没有被创建,就创建一个if (m_MyForm == null || m_MyForm.IsDisposed){// 事件处理的类ExternalEventExample handler = new ExternalEventExample();// 用静态方法 `ExternalEvent.Create()` 创建一个 `ExternalEvent` ExternalEvent exEvent = ExternalEvent.Create(handler);// 把 handler 和 exEvent 都传给这个非模态对话框,最终非模态对话框通过它们来处理用户的请求m_MyForm = new ExternalEventExampleDialog(exEvent, handler);}m_MyForm.Show();}
}[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class Command : IExternalCommand
{public virtual Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements){try{ExternalEventExampleApp.thisApp.ShowForm(commandData.Application);return Result.Succeeded;}catch (Exception ex){message = ex.Message;return Result.Failed;}}
}

Raise Event

通过 m_ExEvent.Raise(),让 Revit 来处理用户的请求。

public partial class ExternalEventExampleDialog : Form
{private ExternalEvent m_ExEvent;private ExternalEventExample m_Handler;public ExternalEventExampleDialog(ExternalEvent exEvent, ExternalEventExample handler){InitializeComponent();m_ExEvent = exEvent;m_Handler = handler;}protected override void OnFormClosed(FormClosedEventArgs e){// we own both the event and the handler// we should dispose it before we are closedm_ExEvent.Dispose();m_ExEvent = null;m_Handler = null;// do not forget to call the base classbase.OnFormClosed(e);}private void closeButton_Click(object sender, EventArgs e){Close();}private void showMessageButton_Click(object sender, EventArgs e){m_ExEvent.Raise();}
}

ModelessForm_ExternalEvent

最终效果如下:

对应的消息处理的类 RequestHandler 实现了 IExternalEventHandler

public void Execute(UIApplication uiapp)
{try{switch (Request.Take()){case RequestId.None:{return;  // no request at this time -> we can leave immediately}case RequestId.Delete:{ModifySelectedDoors(uiapp, "Delete doors", e => e.Document.Delete(e.Id));break;}case RequestId.FlipLeftRight:{ModifySelectedDoors(uiapp, "Flip door Hand", e => e.flipHand());break;}case RequestId.FlipInOut:{ModifySelectedDoors(uiapp, "Flip door Facing", e => e.flipFacing());break;}case RequestId.MakeLeft:{ModifySelectedDoors(uiapp, "Make door Left", MakeLeft);break;}case RequestId.MakeRight:{ModifySelectedDoors(uiapp, "Make door Right", MakeRight);break;}case RequestId.TurnOut:{ModifySelectedDoors(uiapp, "Place door Out", TurnOut);break;}case RequestId.TurnIn:{ModifySelectedDoors(uiapp, "Place door In", TurnIn);break;}case RequestId.Rotate:{ModifySelectedDoors(uiapp, "Rotate door", FlipHandAndFace);break;}default:{// some kind of a warning here should// notify us about an unexpected request break;}}}finally{Application.thisApp.WakeFormUp();}return;
}

每一个动作最终都用调用 ModifySelectedDoors,这里用了策略设计模式,把各种类型的改变都包装成一个函数。ModifySelectedDoors 本身的逻辑很简单,就是把门过滤出来,然后对每个门调用改变的函数。

private void ModifySelectedDoors(UIApplication uiapp, String text, DoorOperation operation)
{UIDocument uidoc = uiapp.ActiveUIDocument;// 判断是否有活动的文档和选择集if ((uidoc != null) && (uidoc.Selection != null)){ICollection<ElementId> selElements = uidoc.Selection.GetElementIds();if (selElements.Count > 0){// 从当前的选择集中过滤出所有的门FilteredElementCollector collector = new FilteredElementCollector(uidoc.Document, selElements);ICollection<Element> doorset = collector.OfCategory(BuiltInCategory.OST_Doors).ToElements();if (doorset != null){using (Transaction trans = new Transaction(uidoc.Document)){// The name of the transaction was given as an argumentif (trans.Start(text) == TransactionStatus.Started){// 对每一个门进行修改foreach (FamilyInstance door in doorset){operation(door);}trans.Commit();}}}}}
}

ModelessForm_IdlingEvent

效果和 ModelessForm_ExternalEvent 一样,差别是处理函数不同。ModelessForm_IdlingEvent 是在 Revit 空闲的时候被调用。
具体逻辑:

  1. 注册 idling 事件
  2. 在idling 处理函数里进行处理

注册 idling 事件

通过 uiapp 来注册空闲事件:

public void ShowForm(UIApplication uiapp)
{// If we do not have a dialog yet, create and show itif (m_MyForm == null || m_MyForm.IsDisposed){m_MyForm = new ModelessForm();m_MyForm.Show();// if we have a dialog, we need Idling toouiapp.Idling += IdlingHandler;}
}

idling 事件处理函数

public void IdlingHandler(object sender, IdlingEventArgs args)
{UIApplication uiapp = sender as UIApplication;if (m_MyForm.IsDisposed){uiapp.Idling -= IdlingHandler;return;}else   // 对话框还打开着{// 从对话框查询用户的请求及内容RequestId request = m_MyForm.Request.Take();if (request != RequestId.None){try{// 调用具体的处理函数,和ModelessForm_ExternalEvent的处理一致RequestHandler.Execute(uiapp, request);}finally{// 激活无模态对话框m_MyForm.WakeUp();}}}return;
}

Revit SDK 介绍:ModelessForm_ExternalEvent ModelessForm_IdlingEvent相关推荐

  1. Revit SDK 介绍:PostCommandWorkflow

    前言 这个例子介绍的是如何改变 Revit 的保存命令的行为. 内容 程序的步骤: 启动监测 修改文件,点击保存 选择 Add revision now 程序逻辑 菜单的创建与菜单文字的切换 在IEx ...

  2. Revit SDK 介绍:API Sketched Winder Stairs 创建扇形踏步楼梯

    前言 SDK 里面一个复杂的创建楼梯的例子. 程序逻辑 选择模型线,如果是两条,这是L行的楼梯,如果选中三条,则是U行的楼梯: 将 UI 界面的参数转化为内部的参数 创建扇形踏步楼梯 选择模型线 入口 ...

  3. 系统SDK介绍-02

    系统SDK介绍 打开相册选择图片 打开相册选择视频 打开相机拍摄图片 打开相机拍摄视频 配置权限: 在info.plist文件中添加需要的权限 相机权限:Privacy - Camera Usage ...

  4. iOS SDK 介绍及导入

    iOS SDK 介绍 环信 SDK 为用户开发 IM 相关的应用提供的一套完善的开发框架.包括以下几个部分: SDK_Core: 为核心的消息同步协议实现,完成与服务器之间的信息交换. SDK: 是基 ...

  5. Revit SDK EXTENSIONS(软件开发工具包扩展)是什么

    Revit SDK EXTENSIONS(软件开发工具包扩展)是什么 Extension SDK 是开发环境,以快速开发为目的,帮助开发者以Revit扩展技术为基础创建活动插件. Extension ...

  6. revit sdk java api,REVIT 2016二次开发环境的搭建

    1.安装REVIT2016软件,这个直接在autodesk上就可以找到,找到直接安装就好了 2.安装VS环境. 3.安装REVIT 2016 SDK 下载地址在http://usa.autodesk. ...

  7. yocto Extensible SDK介绍

    yocto Extensible SDK介绍 使用yocto Extensible SDK 1.1 为什么使用yocto Extensible SDK及其包含了什么 1.2 安装 Extensible ...

  8. ST17H66 低功耗蓝牙SOC开发(1)—— SDK介绍

    目录 1.资料获取 2.开发环境 3.ST17H66开发SDK获取 4.SDK介绍 4.1 components 4.2 example 4.3 lib 4.4 misc 1.资料获取 伦茨17Hxx ...

  9. 叠幻AR SDK介绍

    SDK介绍 叠幻AR SDK是北京叠幻三维科技有限公司拥有完全自主知识产权的增强现实AR核心算法软件套件.叠幻AR SDK在浏览器端(Web)和小程序端通过极致优化增强现实AR的核心算法,为企业客户提 ...

最新文章

  1. vim-go开发环境Tagbar插件和NERTree插件安装
  2. AngularJS模块——module
  3. mysql hive索引_Hive数据仓库--HiveQL视图和索引
  4. 探索性数据分析(EDA):Python
  5. SPOJ COT Count on a tree 主席树
  6. Java成神之路——重入锁、公平非公平锁、自旋锁、读写锁
  7. 【Flink】Flink AM container is launched, waiting for AM container to Register with RM
  8. Linux Python 安装第三方库时报错 package wheel is not installed
  9. Oracle查询时15分钟划分
  10. Error: could not open `C:\Program Files\Java\jre6\lib\i386\jvm.cfg')
  11. 华为私有云的搭建方案_私有云平台搭建物业管理系统
  12. 只要3分钟免费的快速部署自己的网易云API(一)
  13. word打出计算机图形符号,在word插入符号和特殊符号-word技巧-电脑技巧收藏家
  14. 如何轻松查询分析多个快递单号物流到站派件延误件
  15. 数据库如何增加表中字段
  16. 计算机通信机房消防要求,消防专用电话的设置场所及设计要求
  17. 【AVD】NDK MediaCodec 编码中的坑 configure: err(-2147479551) error -38 Fatal signal 4 (SIGILL) ILL_ILLOPC
  18. conflicting requests nothing provides libpq.so.5(RHPG_9.6)(64bit) needed **
  19. 对main 未定义的引用_错误:ID返回1个退出状态(对“ main”的未定义引用)
  20. IDEA常用设置和插件推荐

热门文章

  1. php seekdir,perl 模式匹配总结和shell命令调用方法 (zz)
  2. 基于JAVA中小型饭馆餐饮管理系统计算机毕业设计源码+系统+数据库+lw文档+部署
  3. (转)OpenGL与DirectX 比较
  4. 【论文阅读】[CVPR 2018] PU-Net: Point Cloud Upsampling Network. [tensorflow] [rec. oth.]
  5. linux gianfar 网口驱动源码,基于MPC8313ERDB平台的Marvell88E1111型网卡驱动移植(uboot+kernel)...
  6. 中科大入学考试(数学)
  7. 京东举办首届大数据峰会 打造智能零售大数据“操作系统”
  8. 自动钉木箱机器人_一种木箱生产用自动钉装设备的制作方法
  9. Git 【fatal: The remote end hung up unexpectedly 问题】
  10. 基于VMWare虚拟机搭建Linux集群