很多时候,当我们提交一个事务的时候,Revit会弹出错误框或者警告框,而该错误或警告无法使用Try-Catch捕获。
using (Transaction transaction = new Transaction(RevitDoc))
{
try
{
transaction.Start("TransactionName");
// do your stuff
transaction.Commit();
}
catch (Exception ex)
{
if (transaction.GetStatus() == TransactionStatus.Started)
transaction.RollBack();
}
}
例如像下面的错误:
这个时候就要用到FailureProcessor了。
首先我们需要定义一个实现了接口IFailuresPreprocessor的类。
public class MyFailuresPreProcessor : IFailuresPreprocessor
{
private string _failureMessage;
private bool _hasError;
public string FailureMessage
{
get { return _failureMessage; }
set { _failureMessage = value; }
}
public bool HasError
{
get { return _hasError; }
set { _hasError = value; }
}
public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
{
var failures = failuresAccessor.GetFailureMessages();
if (failures.Count == 0)
return FailureProcessingResult.Continue;
foreach (var failure in failures)
{
if (failure.GetSeverity() == FailureSeverity.Error)
{
_failureMessage = failure.GetDescriptionText(); // get the failure description
_hasError = true;
return FailureProcessingResult.ProceedWithRollBack;
}
if (failure.GetSeverity() == FailureSeverity.Warning)
{
failuresAccessor.DeleteWarning(failure);
}
}
return FailureProcessingResult.Continue;
}
}
这里通过PreprocessFailures方法我们就可以捕获错误或者警告,然后进行我们想要的处理。
- FailuresAccessor.GetFailureMessages() 获取所有的失败信息
- FailureMessageAccessor.GetSeverity() 可以得知它是警告还是错误
- FailureMessageAccessor.GetDescriptionText() 可以获取错误的文字
- FailureMessageAccessor.GetFailureDefinitionId() 获取失败的定义
- FailuresAccessor.DeleteWarning删除警告,或者FailuresAccessor.DeleteAllWarnings直接删除所有警告
然后在Transaction类里面设置FailuresPreprocessor,使用FailureHandlingOptions options = transaction.GetFailureHandlingOptions();
获取FailureHandlingOptions,然后使用options.SetFailuresPreprocessor(IFailuresPreprocessor)来设置FailuresPreprocessor。
代码如下:
using (Transaction transaction = new Transaction(RevitDoc))
{
try
{
transaction.Start("TransactionName");
FailureHandlingOptions options = transaction.GetFailureHandlingOptions();
MyFailuresPreProcessor failureProcessor = new MyFailuresPreProcessor();
options.SetFailuresPreprocessor(failureProcessor);
transaction.SetFailureHandlingOptions(options);
// do your operations
var status = transaction.Commit();
if (status != TransactionStatus.Committed)
{
if (failureProcessor.HasError)
{
TaskDialog.Show("ERROR", failureProcessor.FailureMessage);
}
}
}
catch (Exception ex)
{
if (transaction.GetStatus() == TransactionStatus.Started)
transaction.RollBack();
}
}