Building Coder(Revit 二次开发) - 失败处理API(下)
2011-09-30 14:43
471 查看
Building Coder 链接:Failure API Take Two
Revit 二次开发论坛链接:翻译 Building Coder - 失败处理API(下)
错误处理
正常情况下,被报告的失败会在事务提交时由 Revit 标准的失败解决 UI 来处理。用户会看到相关信息和可能的处理选项。当然,如果对文档的操作要求对一些特定(或者所有)错误做特殊处理的话,程序员就需要自定义失败解决方案了。
Revit 会在所有事务的提交阶段检测是否存在失败。一旦发现,Revit 会进入一个重复的失败解决周期。每个周期又包含三个步骤:
1. 失败预处理(IFailurePreprocessor)
2. 失败处理事件(FailureProcessing Event)
3. 最终处理(IFailureProcessor)
在一个周期中这三个步骤被依次执行。每个步骤都能控制本步骤的行为和是否进入下一个步骤(通过返回不同的 FailureProcessingResults 值)。已知事务时,可以使用 IFailuresPreprocessor。如果需要处理所有可能的错误,则应使用 FailureProcessing Event。终极解决方案是 IFailureProcessor,它能完全取代 Revit 的标准失败处理。
实现 IFailuresPreprocessor 接口和它的 PreprocessFailures() 方法来处理失败。注册事件并且定义处理器来处理失败。实现 IFailureProcessor 接口和它的 ProcessFailures() 方法来实现最终的失败处理。
每一步我们都可以删除元素,删除警告信息,解决或者报告一个失败。所有的动作都可以被封装在 FailuresAccessor 类中。
处理警告
下面让我们来看一个警告处理的例子。在试图删除被链接模型的最后一个实例时,如果没有实现建立失败处理机制,Revit 会报告如下警告信息:
用户可以手动单击三个按钮来选择处理方式。如果利用失败处理 API,我们就可以模拟用户的手动操作了。首先我们使用一个事件来处理这个警告。你可以如下面代码所示的
那样定义事件处理器,并在一个外部命令中注册 FailuresProcessing 事件:
以上代码展示了两种处理警告的方式。没有被注释掉的那部分代码是其中一个方式:即解决该警告,而后被链接模型和被链接文件都被删除。如果你注释掉代码
failuresAccessor.ResolveFailure(fma)同时取消对代码failuresAccessor.DeleteWarning(fma)的注释,被链接模型依然会被删除但是被链接文件将保留。
重现这个问题的步骤如下:
1. 使用以上代码创建一个外部命令
2. 在 Revit 中创建一个新文档
3. 运行外部命令来注册失败处理器
4. 在新文档中导入模型
5. 使用 Revit“删除”命令删除被链接的模型
警告预处理
接下来我们聊聊如何预处理警告。我们只需要注册一个实现了 IFailuresPreprocessor 接口的类到事务中就可以了。
失败预处理只适用于事务动作导致的失败。在上面的例程中,我们先选中被链接模型然后在事务中删除它。可以看到核心代码和之前的事件处理机制类似。
本文只是对失败处理做简单介绍,Revit 2011 SDK 中有例程 ErrorHandling 展示了更多的细节。当然你也可以在开发文档的第26章找到详细叙述。
Revit 二次开发论坛链接:翻译 Building Coder - 失败处理API(下)
错误处理
正常情况下,被报告的失败会在事务提交时由 Revit 标准的失败解决 UI 来处理。用户会看到相关信息和可能的处理选项。当然,如果对文档的操作要求对一些特定(或者所有)错误做特殊处理的话,程序员就需要自定义失败解决方案了。
Revit 会在所有事务的提交阶段检测是否存在失败。一旦发现,Revit 会进入一个重复的失败解决周期。每个周期又包含三个步骤:
1. 失败预处理(IFailurePreprocessor)
2. 失败处理事件(FailureProcessing Event)
3. 最终处理(IFailureProcessor)
在一个周期中这三个步骤被依次执行。每个步骤都能控制本步骤的行为和是否进入下一个步骤(通过返回不同的 FailureProcessingResults 值)。已知事务时,可以使用 IFailuresPreprocessor。如果需要处理所有可能的错误,则应使用 FailureProcessing Event。终极解决方案是 IFailureProcessor,它能完全取代 Revit 的标准失败处理。
实现 IFailuresPreprocessor 接口和它的 PreprocessFailures() 方法来处理失败。注册事件并且定义处理器来处理失败。实现 IFailureProcessor 接口和它的 ProcessFailures() 方法来实现最终的失败处理。
每一步我们都可以删除元素,删除警告信息,解决或者报告一个失败。所有的动作都可以被封装在 FailuresAccessor 类中。
处理警告
下面让我们来看一个警告处理的例子。在试图删除被链接模型的最后一个实例时,如果没有实现建立失败处理机制,Revit 会报告如下警告信息:
用户可以手动单击三个按钮来选择处理方式。如果利用失败处理 API,我们就可以模拟用户的手动操作了。首先我们使用一个事件来处理这个警告。你可以如下面代码所示的
那样定义事件处理器,并在一个外部命令中注册 FailuresProcessing 事件:
public class RegisterFailureEvent : IExternalCommand { public Result Execute( ExternalCommandData commandData, ref string messages, ElementSet elements ) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; app.Application.FailuresProcessing += new EventHandler<FailuresProcessingEventArgs>( OnFailuresProcessing ); return Result.Succeeded; } /// <summary> /// 事件处理器 /// </summary> private void OnFailuresProcessing( object sender, FailuresProcessingEventArgs e ) { FailuresAccessor failuresAccessor = e.GetFailuresAccessor(); String transactionName = failuresAccessor.GetTransactionName(); IList<FailureMessageAccessor> fmas = failuresAccessor.GetFailureMessages(); if( fmas.Count == 0 ) { // 允许失败处理周期进入下一个步骤 e.SetProcessingResult( FailureProcessingResult.Continue ); return; } // 如果手动删除一个元素,事务名称为 'Delete Selection' if( transactionName.Equals( "Delete Selection" ) ) { foreach( FailureMessageAccessor fma in fmas ) { // 模拟手动单击"Remove Link"按钮 failuresAccessor.ResolveFailure( fma ); // 模拟手动单击"Ok"按钮 //failuresAccessor.DeleteWarning(fma); } e.SetProcessingResult( FailureProcessingResult.ProceedWithCommit ); return; } e.SetProcessingResult( FailureProcessingResult.Continue ); } }
以上代码展示了两种处理警告的方式。没有被注释掉的那部分代码是其中一个方式:即解决该警告,而后被链接模型和被链接文件都被删除。如果你注释掉代码
failuresAccessor.ResolveFailure(fma)同时取消对代码failuresAccessor.DeleteWarning(fma)的注释,被链接模型依然会被删除但是被链接文件将保留。
重现这个问题的步骤如下:
1. 使用以上代码创建一个外部命令
2. 在 Revit 中创建一个新文档
3. 运行外部命令来注册失败处理器
4. 在新文档中导入模型
5. 使用 Revit“删除”命令删除被链接的模型
警告预处理
接下来我们聊聊如何预处理警告。我们只需要注册一个实现了 IFailuresPreprocessor 接口的类到事务中就可以了。
[TransactionAttribute( TransactionMode.Manual )] [RegenerationAttribute( RegenerationOption.Manual )] public class FailureHandle : IExternalCommand { public Result Execute( ExternalCommandData commandData, ref string messages, ElementSet elements ) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; Transaction trans = new Transaction( doc, "DeleteLinkedModel" ); trans.Start(); FailureHandlingOptions options = trans.GetFailureHandlingOptions(); MyPreProcessor preproccessor = new MyPreProcessor(); options.SetFailuresPreprocessor( preproccessor ); trans.SetFailureHandlingOptions( options ); Selection sel = app.ActiveUIDocument.Selection; Reference ref1 = sel.PickObject( ObjectType.Element, "Please pick a linked model instance" ); Element elem = ref1.Element; doc.Delete( elem ); trans.Commit(); return Result.Succeeded; } } /// <summary> /// 定义失败预处理器 /// </summary> public class MyPreProcessor : IFailuresPreprocessor { FailureProcessingResult IFailuresPreprocessor.PreprocessFailures( FailuresAccessor failuresAccessor ) { String transactionName = failuresAccessor.GetTransactionName(); IList<FailureMessageAccessor> fmas = failuresAccessor.GetFailureMessages(); if( fmas.Count == 0 ) { return FailureProcessingResult.Continue; } // 这里我们假设已经知道了事务的名称 if( transactionName.Equals( "DeleteLinkedModel" ) ) { foreach( FailureMessageAccessor fma in fmas ) { // 模拟手动单击"Remove Link"按钮 failuresAccessor.ResolveFailure( fma ); // 模拟手动单击"OK"按钮 //failuresAccessor.DeleteWarning( fma ); } return FailureProcessingResult.ProceedWithCommit; } return FailureProcessingResult.Continue; } }
失败预处理只适用于事务动作导致的失败。在上面的例程中,我们先选中被链接模型然后在事务中删除它。可以看到核心代码和之前的事件处理机制类似。
本文只是对失败处理做简单介绍,Revit 2011 SDK 中有例程 ErrorHandling 展示了更多的细节。当然你也可以在开发文档的第26章找到详细叙述。
相关文章推荐
- Building Coder(Revit 二次开发) - 失败处理API(上)
- Building Coder(Revit 二次开发) - 可扩展存储处理字典
- Building Coder(Revit 二次开发) - ToElementIds() 的性能
- Building Coder(Revit 二次开发) - 元素层级事件(下)
- Revit 二次开发 - 多文档处理
- AEC DevBlog(Revit 二次开发)- 使用 Revit API 选取三维点
- Building Coder(Revit 二次开发) - GetInstanceGeometry() 的开销和无效的引用
- Building Coder(Revit 二次开发)- 图形化显示区域边界
- Revit 2012 二次开发最新API网络课程录像下载
- Building Coder(Revit 二次开发) - 缺少层(Level)属性的族实例
- Building Coder(Revit 二次开发) - 族元素可见性
- Revit API 历史回顾,二次开发现状和中国二次开发的展望
- Building Coder(Revit 二次开发) - 拖放API
- Revit API 二次开发插件之快速管综插件帮助文档
- Building Coder(Revit 二次开发)- 使用实体相交(Solid Intersection)过滤有接触的梁
- Building Coder(Revit 二次开发) - 改变元素颜色
- Building Coder(Revit 二次开发) - 族符号与族类型
- Building Coder(Revit 二次开发) - UIView 和 Windows 设备坐标
- Building Coder(Revit 二次开发)- 创建球体用于AVF和过滤
- Building Coder(Revit 二次开发) - 对象关系