經常我們對一些元素進行更改后,需要出發其他元素的調整,比如我們定義一種牆體,這個牆體的門永遠在牆的中心,那么當改變牆體的長度的時候,則需要自動調整門洞的位置。
我們肯定想得到,用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(); } }
