经常我们对一些元素进行更改后,需要出发其他元素的调整,比如我们定义一种墙体,这个墙体的门永远在墙的中心,那么当改变墙体的长度的时候,则需要自动调整门洞的位置。
我们肯定想得到,用DocumentChanged事件,一旦文档发生改变,则调用当前事件,发现墙体变化了去修改门洞,但当前方法会造成一个巨大的安全隐患,你修改墙体-DocumentChanged-修改门窗-DocumentChanged--会出现一个事件的循环调用,造成当前修改无法完成,要实现以上功能,则需要利用revit提供的机制DMU功能(Dynamic Model Update)。
DMU被称为动态模型更新,他会根据修改的模型信息,调整自己或者其他模型。
案例如下:
1、注册一个更新RegisterUpdater
通过以下代码,可以向当前的文档中注册一个更新元素
//定义一个更新
SpatialFieldUpdater updater = new SpatialFieldUpdater(container,uiApp.ActiveAddInId);
//向文档中注册一个更新对象 if (!UpdaterRegistry.IsUpdaterRegistered(updater.GetUpdaterId())) UpdaterRegistry.RegisterUpdater(updater, doc);
2、添加一个监听AddTrigger接口
//添加要监听的对象 IList<ElementId> idCollection = new List<ElementId>(); idCollection.Add(element.Id); UpdaterRegistry.RemoveAllTriggers(s_updaterId); //添加一个监听行为,主要对添加的元素进行监听 UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), doc, idCollection, Element.GetChangeTypeGeometry());
通过以上的监听,实现了对传入的elementId进行了监听。AddTrigger函数主要三个重载,分别是:
AddTrigger(UpdaterId, ElementFilter, ChangeType) 对过滤的对象进行监听‘
AddTrigger(UpdaterId, Document, ElementFilter, ChangeType) 对指定文档的过滤元素进行监听
AddTrigger(UpdaterId, Document, ICollection<(Of <<'(ElementId>)>>), ChangeType) 对指定文档,指定集合的元素进行监听
可以通过Element的以下方法,来获取需要监听的改变事件,如下表:
编号 |
方法 |
说明 |
1 |
GetChangeTypeAny |
元素的任意改变 |
2 |
GetChangeTypeElementAddition |
元素的添加 |
3 |
GetChangeTypeElementDeletion |
元素的删除 |
4 |
GetChangeTypeGeometry |
元素的图形的改变 |
5 |
GetChangeTypeParameter(ElementId) |
指定元素的参数改变 |
6 |
GetChangeTypeParameter(Parameter) |
参数的值改变 |
ChangeType主要是元素监听的类型,可以通过元素的各种GetChangeType类获取,以下定义,如果元素的空间字段发生改变,则实现更新
3、注册更新元素
主要用于对以上监听的对象,图形发生变化的时候,需要做的处理,如下
public class SpatialFieldUpdater : IUpdater { public string GetAdditionalInformation() { return "AVF DMU Thread sample"; } public ChangePriority GetChangePriority() { return ChangePriority.FloorsRoofsStructuralWalls; } public UpdaterId GetUpdaterId() { return s_updaterId; } public string GetUpdaterName() { return "AVF DMU Thread"; } public SpatialFieldUpdater(MultithreadedCalculationContainer _container, AddInId addinId) { containerOld = _container; s_updaterId = new UpdaterId(addinId, new Guid("FBF2F6B2-4C06-42d4-97C1-D1B4EB593EFF")); } public void Execute(UpdaterData data) { UIApplication uiApp = new UIApplication(data.GetDocument().Application); uiApp.Idling -= containerOld.UpdateWhileIdling; containerOld.Stop(); Document doc = data.GetDocument(); View activeView = doc.GetElement(s_activeViewId) as View; SpatialFieldManager sfm = SpatialFieldManager.GetSpatialFieldManager(activeView); sfm.Clear(); } }