一.起因   

自己在写revit二开时,有一个Winform窗体按钮点击事件需要 触发调用事务进行处理,结果出现“异常“Starting a transaction from an external application running outside of API context is not allowe“”

其实这是 上面异常是Revit的一种保护机制,创建的非模态对话框Form1后,在Form1未关闭的状态下,Revit认为是处于非API的上下文环境,所以异常弹出来了。

在非模态对话框打开的状态下,调用Transaction必须通过Idling或者ExternalEvent API进行相关代码调用;在SDK Sample安装包下面,有个例子程序叫ModelessDialog详细介绍了Idling及ExternalEvent的调用机制。

在Revit 2014之前的版本,当非模态对话框打开的状态,调用Transaction是可以的,但是从Revit 2014之后因为考虑安全等方面被禁止了。

二.解决办法与代码

非模态窗口有一个好处,就是可以一直停留在程序之前,然后持续完成操作。但是在Revit二次开发中,非模态窗口也有几个注意事项。

1、需要在文档关闭的时候,把非模态窗口也关闭掉,不然会导致文档关闭,窗口还在这样奇怪的Bug。

2、非模态的窗口的事件需要在IExternalCommand里注册。

3、每个操作必须在外部事件里进行。

2.1 第一步:注册外部事件

                             

              2.2 第二步:Form内使用

                         

在Form构造函数或者Load事件内:

我Form窗体内有一个TreeList控件,控件鼠标点击事件触发 外部事件:

GetSelectedDistributionProLevel()为获取当前TreeList鼠标选中的Node信息,DistributionProjectLevelData为自己定义的Class

m_elecGridLayingOpe.SetGridLineElementSelected(app, node.LevelUniqueID)里面的代码如下:

其中UniqueId为Element的UniqueId.

三.焦点(关键点)

在Revit二次开发中,如果使用了非模态窗体,设置好参数输入后,点击按钮命令后,Revit没有立刻进入到激活状态,当前的窗体仍然是非模态窗体。以前我会在点击按钮中加入一句:this.Close(),直接关闭非模态窗体,这种方式太粗暴。

究其原因:在做的非模态窗体在执行相应命令后,窗体并没有关闭或是隐藏,就一直处于激活状态,导致Rveit不能立刻激活或者取到焦点。解决办法:使用WindowsAPI下的两个函数 GetActiveWindow(),SetActiveWindow(IntPtr hwnd),一个是获得当前系统获得焦点的窗体句柄,一个是设置当前系统某个窗体获得焦点。

为获得Rveit的窗体句柄,需要添加引用:AdWIndows.dll

代码如下:

在Form构造函数内:

在TreeList鼠标点击事件函数内:

Revit二次开发——非模态窗口的事件处理的更多相关文章

  1. Revit二次开发环境配置(Revit 2020 +Visual Studio 2019)

    Revit二次开发环境搭建(Revit 2019+Visual Studio 2017)准备内容 Revit 2019开发环境的搭建,需要安装的内容如下: Revit 2019(主要的开发环境) Vi ...

  2. revit二次开发wpf里button按钮无法实现事务

    不能在revit提供的api外部使用事务,解决此方法, 1.把button里要实现的功能写到外部事件IExternalEventHandler中,注册外部事件,在button事件中.raise()使用 ...

  3. Revit二次开发实现BIM盈利(以橄榄山快模为例解说) 视频讲座下载

    应笔墨闲谈群的邀请, 在10月11号晚8:30分在其群做了一次关于BIM二次开发的讲座. 因为參与者基本上都是从设计院和施工单位来的,所以对Revit二次开发做了纵览性的解说, 以非程序猿能听懂的方式 ...

  4. Revit二次开发-BIM模型导出

    最近一个月一直在研究Revit二次开发-BIM模型的导出,在网上找了很多相关资料学习.下面简单介绍一下我最近做的这个BIM模型的导出功能. 开始尝试使用Revit2015的样例程序里提供的读取模型几何 ...

  5. Revit二次开发之绘制钢筋

    第一次在博客园上写东西,也不知道该写些什么,我想就写点最近项目到遇到的问题吧. 最近在做一个小项目,具体需求大概是在一个revit模型中的对应的楼板位置绘制钢筋. 由于刚接触Revit二次开发,之前也 ...

  6. js实现非模态窗口增加数据后刷新父窗口数据

    父窗口是由两个部分组成,一个html的table,一部分是extjs的gird. 点击grid面板[增加]按钮将会弹出非模态窗口进行新数据的编辑页面 下面是按钮的触发函数代码: var a = win ...

  7. Revit二次开发初体验

    最近换了下工作,由之前的互联网企业转入了BIM软件开发行列.具体原因不多说,作为一个程序员来说学习永无止境.下面来一个Hello World体验下Revit的二次开发 事前准备 VS Revit 20 ...

  8. Revit二次开发 推荐

    学习revit二次开发,建议还是先把revit熟悉一下,去建立一下模型,亲自感受一下是如何创建模型的流程,其中会遇到什么问题.这样在自己做二次开发的时候,一些问题自己就能提前想到,规避掉.我大概用了半 ...

  9. [转载]弹出一个不带地址栏、工具栏的IE非模态窗口

    标签:ie /非模态窗口 window.open(url,'_blank','menubar=no,fullscreen=1,toolbar=no,resizable=no,location=no,s ...

随机推荐

  1. Bash 脚本编程

    概述 Bash (GNU Bourne-Again Shell) 是许多Linux发行版的默认Shell. shell语法 变量 定义:your_name="hellohhy" 使 ...

  2. union注入

    union注入 更多内容请看此链接:https://blog.csdn.net/weixin_45380284 1.判断是否存在注入: 方法一: 单引号法--在url最后加一个单引号,如: http: ...

  3. RabbitMQ 入门之基础概念

    什么是消息队列(MQ) 消息是在不同应用间传递的数据.这里的消息可以非常简单,比如只包含字符串,也可以非常复杂,包含多个嵌套的对象.消息队列(Message Queue)简单来说就是一种应用程序间的通 ...

  4. finalize()和四种引用的一点思考

    一次对ThreadLocal的学习引发的思考 ThreadLocal对Entry的引用是弱引用,于是联想到四种引用的生命周期. 强引用,不会进行垃圾回收 软引用,JVM内存不够,进行回收 弱引用,下次 ...

  5. 跟老刘学运维day02~新手必须掌握的Linux命令(2)

    第2章 Linux命令 1.Shell 计算机硬件:由运算器.控制器.存储器.输入/输出设备等共同组成 Shell:人与硬件的翻译官,人要想使用硬件,需要服务程序 Bash四大好处: (1)通过上下方 ...

  6. sed 指定行范围匹配

    sed -n '5,10{/pattern/p}' file sed是一个非交互性性文本编辑器,它编辑文件或标准输入 导出的文件拷贝.标准输入可能是来自键盘.文件重定向.字符串或变量,或者是一个管道文 ...

  7. HttpServletRequest、HttpServletResponse

    doGet()/doPost()方法都有两个参数,一个为代表请求的request,另一个代表响应response. request是获取前台传递的内容,response是反馈给前台数据 HttpSer ...

  8. HTML5其他标签应用

    HTML5 是下一代 HTML 标准. HTML5 多媒体 音频标签 <audio src=" "></audio> 视频标签 <video src= ...

  9. JVM详解之:HotSpot VM中的Intrinsic methods

    目录 简介 什么是Intrinsic Methods 内置方法的特点 多样性 兼容性 java语义的扩展 Hotspot VM中的内置方法 intrinsic方法和内联方法 intrinsic方法的实 ...

  10. PHP var_export() 函数

    var_export() 函数用于输出或返回一个变量,以字符串形式表示.高佣联盟 www.cgewang.com高佣联盟 www.cgewang.com var_export() 函数返回关于传递给该 ...