Revit二次开发之双事件:空闲事件与DocumentChanged事件

来源:互联网 发布:新奔腾预算软件 编辑:程序博客网 时间:2024/05/22 17:24

对以下文章所展示的代码进行了修改,当前展示的代码可直接复制使用。

由于本人初学,下列语言为个人理解,如有错误请指正。


《引用1》中:

  • 使用模态对话框,或者尽量保证事件在ExternalCommand的Execute函数或者ExternalApplication的OnStartup函数里面注册。
  • 如果一定要使用非模态对话框,那么请使用ExternalEvent事件的Raise函数,强迫程序进入Revit主线程,然后在里面进行注册事件。


因为《引用1》和《引用2》都没有OnStartup,所以再没有例子的情况下暂时不会使用。

《原文章出处》:双事件使用时,IExternalCommand的Execute函数中进行了注册,在各自的响应函数中进行了注销

《引用1》:为WinFrom程序,并且同时有Raise函数和注册/注销行为,因为没用过WinFrom感觉不会用、没看懂。。。

《引用2》:为WPF程序,并且使用非模态对话框的使用情况,没有注册和注销行为。

 

对比三篇文章的时间,更倾向于参考《原文章出处》《引用2》,《引用1》的内容稍后会再进行复盘。【有更好的例子请回复告知】


原文章出处(2016-09-28):http://blog.sina.com.cn/s/blog_16796559b0102y8ey.html

引用1(2015-09-09):RevitAPI: 注意Revit 2016事件注册和注销行为的改变

引用2(2016-09-20):Revit开发之外部事件IExternalEventHandler

引用2中的例子本人重新练习做的个人笔记,代码可直接复制使用:Revit开发之非模态对话框下的外部事件 WPF

环境:Revit2016

原文:

前段时间做Revit开发项目时遇到一个棘手的问题,我们都知道Revit运行环境是不允许多线程并发的,也就是说同一时刻只能有一个事务或操作运行,然后可以根据具体情况去触发不同的响应事件,如DocumentOpend,DocumentChanged等,那么问题是什么呢?问题是有时我们希望通过外部命令PostCommand调用Revit本身的命令,如调用绘制桥架命令,但是我们希望在此命令执行后去触发事件,后来经过测试发现PostCommand不会阻止线程的运行,而且还是外部命令运行完后才触发,那么我们就无法拿到PostCommand触发完成后的事件了,所以我们需要一个全局监控事件,来监控活动文档的改变,所以想到了DocumentChanged事件。但是发现在DocumentChanged事件里不能开始事务,也没用了,最后想到用Revit空闲事件和DocumentChanged事件相结合来做,首先我们在外部命令下注册这两个事件,由DocumentChanged事件触发空闲事件,在空闲事件里执行响应的事务,最后再注销两个事件,到此问题得到有效解决。当然除了Idling还可以用ExternalEvent来做配合!


本代码实现调用PostCommand命令放置一个门,然后触发相应的事件再删除此门,也可以扩展其他功能,本目的就是为了测试事务是否能成功开启


新代码为:


using Autodesk.Revit.UI;using Autodesk.Revit.DB;using Autodesk.Revit.Attributes;using Autodesk.Revit.UI.Selection;using Autodesk.Revit.DB.Plumbing;using Autodesk.Revit.DB.Mechanical;using System.Xml;using Autodesk.Revit.UI.Events;using System;using System.Collections.Generic;using System.Linq;using Autodesk.Revit.DB.Events;namespace HelloWorld{    [Transaction(TransactionMode.Manual)]    [Regeneration(RegenerationOption.Manual)]    public class Test : IExternalCommand    {  //定义一个字段通过属性变化来触发空闲事件        public static Boolean IdleFlag = false;        //记录DocumentChanged事件发生改变的构件        IList<ElementId> listId = new List<ElementId>();        //定义一个全局UIApplication,用来注销指定事件        UIApplication uiApp = null;        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)        {            uiApp = commandData.Application;            UIDocument uiDoc = uiApp.ActiveUIDocument;            Document Doc = uiDoc.Document;            uiApp.PostCommand(RevitCommandId.LookupPostableCommandId(PostableCommand.Door));            uiApp.Idling += new EventHandler<IdlingEventArgs>(IdlingHandler);            uiApp.Application.DocumentChanged += new EventHandler<DocumentChangedEventArgs>(DocumentChangedForSomething);            return Result.Succeeded;        }        private void DocumentChangedForSomething(object sender, DocumentChangedEventArgs e)        {            listId.Clear();            ICollection<ElementId> collection = e.GetAddedElementIds();            listId.Add(collection.ElementAt(0));            IdleFlag = true;            uiApp.Application.DocumentChanged -= new EventHandler<DocumentChangedEventArgs>(DocumentChangedForSomething);        }        //Revit空闲事件        public void IdlingHandler(object sender, IdlingEventArgs args)        {            UIApplication uiapp = sender as UIApplication;            if (!IdleFlag)            {                return;            }            ExecuteIdlingHandler.Execute(uiapp, listId);            IdleFlag = false;            uiApp.Idling -= new EventHandler<IdlingEventArgs>(IdlingHandler);        }    }    public static class ExecuteIdlingHandler    {        public static void Execute(UIApplication uiapp, IList<ElementId> listId)        {            UIDocument uidoc = uiapp.ActiveUIDocument;            if (uidoc != null)            {                Transaction ts = new Transaction(uidoc.Document, "delete");                ts.Start();                uidoc.Document.Delete(listId);                ts.Commit();            }        }    }}


阅读全文
0 0
原创粉丝点击