当你关心的构件(注册时)行为发生改变时(它甚至可以只针对某个参数进行监听),revit会通过回调的方式相应该事件。
你的应用场景可能有:
1、用户插入门时,自动调整门距墙的距离;
2、实时统计项目中门窗的个数;
3、删除某构件时,同时自动删除它的附属构件等等操作。
class UpdaterTemplateService : IUpdater
{
const string UpdaterId = "082604f4-9551-4bd3-b676-d5e10fb99577";
readonly AddInId _appId = null;
readonly UpdaterId _updaterId = null;
/// <summary>
///
/// </summary>
/// <param name="addInGuid">addin文件的ID</param>
UpdaterTemplateService(Guid addInGuid)
{
System.Diagnostics.Debug.Assert(addInGuid != null && addInGuid != Guid.Empty);
_appId = new AddInId(addInGuid);
_updaterId = new UpdaterId(_appId, new Guid(UpdaterId));
}
#region IUpdater
public void Execute(UpdaterData data)
{
try
{
var document = data.GetDocument();
//TODO....
//只能写子事务
}
catch (Exception ex)
{
App.Instance.Loger.Error(ex);
System.Windows.MessageBox.Show(
ex.Message,
"错误消息",
System.Windows.MessageBoxButton.OK,
System.Windows.MessageBoxImage.Error);
}
}
public string GetAdditionalInformation()
{
return "DMU的描述,附加信息";
}
public ChangePriority GetChangePriority()
{
return ChangePriority.Views;
}
public UpdaterId GetUpdaterId()
{
return _updaterId;
}
public string GetUpdaterName()
{
return "DMU名称";
}
#endregion
public static void RegisterUpdater(Guid addInGuid)
{
var updateSrv = new UpdaterTemplateService(addInGuid);
var updateId = updateSrv.GetUpdaterId();
if (!UpdaterRegistry.IsUpdaterRegistered(updateId))
{
UpdaterRegistry.RegisterUpdater(updateSrv, false);
var filter = new ElementClassFilter(typeof(FamilyInstance));
/*
* 对FamilyInstance元素的增加和删除监听
*
* 如果需要关注某些有自己程序创建出来的Element,可以把每个Element附上扩展数据
* 然后使用ExtensibleStorageFilter过滤器注册DMU即可
*
* DUM对用户的Ctrl + Z 无效, 可以在DocumentChanged事件中完善该机制
*/
UpdaterRegistry.AddTrigger(
updateId,
filter,
Element.GetChangeTypeElementAddition());
UpdaterRegistry.AddTrigger(
updateId,
filter,
Element.GetChangeTypeElementDeletion());
}
}
}
UpdaterId需要任意唯一的ID
public static void RegisterUpdater(Guid addInGuid)注册接口需要的ID为当前插件的Addin,可在OnStartup接口中获取,如下:
var addinId = application.ActiveAddInId.GetGUID();
上面代码关心FamilyInstance类别元素的增和删的操作;
revit提供了很多过滤器,仔细研究,其实它分得很细,大部分情况下能恰到好处的过滤出你关心的模型内容。
如代码注释中的描述,扩展说说DocumentChanged事件,其实在该事件中能实现撤销的操作。
比如说禁止Ctrl+V的元素拷贝,直接在该事件中给revi窗口发送Ctrl + Z的消息即可,这路子是野了点,不过效果还是不错的。