【Revit二次开发】事务和事务处理(Transaction and FailureHandlingOptions)

事务基础

事务是将一系列修改Revit模型的操作提交至文档的这样一种对象。 任何一个对文档修改的操作都需要包含在-一个打开的属于该文档的事务中,否则就会有异常抛出。任何修改都要在事务提交后才写人文档。在一个事务中进行的所有修改都能被撤销。在任何时候,一个文档当前只能有一个打开的事务,但在一个事务中可以有一个或多个修改模型的操作。
事务是将一系列修改Revit模型的操作提交到文档的一种对象。任何一个对文档修改的操作都要包含在一个打开的属于该文档的食物中。

和事务有关的主要有三个类:

  • Transaction事务
  • SubTransaction子事务
  • TransactionGroup事务组

注意:
①用于IExternalCommand 的TransactionMode属性会影响该命令在被执行时Revi对事务的处理。
②如果一个事务从其他线程或在模态对话框之外启动会导致异常发生。事务只能从API支持的环境中启动,比如外部命令、事件等。

通用事务方法

方法描述
Start启动事务
Commit结束事务并提交所有的修改到文档中
RollBack结束事务并撤销对文档所做的所有的修改
GetStatus返回当前事务状态

Transaction类

要修改Revil 文档中的模型就需要一个Transaction。 在同一时间,只有一个Transaction可以被打开,不允许嵌套。每个Transaction需要一个名字,当这个Transaction被成功提交后,这个名字会被显示在Undo菜单里。

FailureHandlingOptions

控制在事务结束时如何处理故障(如果在事务期间发生了任何故障)的选项。

编写代码

using System;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;

namespace HelloRevitTransaction
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    public class RevitTransactionCmd : IExternalCommand
    {
        public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            try
            {
                //获取文档
                Document doc = commandData.Application.ActiveUIDocument.Document;
  				//会修改Revit文档模型的操作需要事务
                //创建transaction来执行命令
                // 任何Transaction要放在 “using”中创建来保证它被正确的结束,而不会影响到其他地方
                using (Transaction transaction = new Transaction(doc))
                {
                    if (transaction.Start("事务") == TransactionStatus.Started)
                    {
                        Line line = Line.CreateBound(XYZ.Zero, XYZ.BasisX);
                        Wall wall = Wall.Create(doc, line, new ElementId(311), false);

                        //提交
                        //由于种种原因,如果修改或创建的模型不正确,
						//这个Transaction可能不会被正确提交
						//如果一个Transaction失败了或被用户取消了,
						//那么返回的状态就是RolledBack,而不是Committed。
                        try
                        {
                        	TaskDialog taskDialog = new TaskDialog("Revit");
        					taskDialog.MainContent = "Click either [OK] to Commit, or [Cancel] to Roll back the transaction.";
       						TaskDialogCommonButtons buttons = TaskDialogCommonButtons.Ok | TaskDialogCommonButtons.Cancel;
        					taskDialog.CommonButtons = buttons;

        					if (TaskDialogResult.Ok == taskDialog.Show())
        					{
                            	if (TransactionStatus.Committed != transaction.Commit())
                            	{
                                	TaskDialog.Show("事务入门", "提交失败!");
                            	}
                            }
                        }
                        //回滚
                        catch
                        {
                            transaction.RollBack();
                        }
                    }
                }
                return Autodesk.Revit.UI.Result.Succeeded;
            }
            catch (Exception ex)
            {
                message = ex.Message;
                return Autodesk.Revit.UI.Result.Failed;
            }
        }
    }
}

事务提交后,Revit会管理事务中发生的错误和警告。当错误发生时,事务将会抛出异常。当警告发生时,Revit的故障处理程序将会以默认的方式处理警告。

public void CompoundOperation(Autodesk.Revit.DB.Document document)
{
  // 所有TransactionGroup要用“using”来创建来保证它的正确结束
  using (TransactionGroup transGroup = new TransactionGroup(document, "Level and Grid"))
  {
     if (transGroup.Start() == TransactionStatus.Started)
     {
        // 我们打算调用两个函数,每个都有一个独立的事务
        // 我们打算这个组合操作要么成功,要么失败
        // 只要其中有一个失败,我们就撤销所有操作

        if (CreateLevel(document, 25.0) && CreateGrid(document, new XYZ(0, 0, 0), new XYZ(10, 0, 0)))
        {
           // Assimilate函数会将这两个事务合并成一个,并只显示TransactionGroup的名字
           // 在Undo菜单里
           transGroup.Assimilate();
        }
        else
        {
           // 如果有一个操作失败了,我们撤销在这个事务组里的所有操作
           transGroup.RollBack();
        }
     }
  }
}

public bool CreateLevel(Autodesk.Revit.DB.Document document, double elevation)
{
  using (Transaction transaction = new Transaction(document, "Creating Level"))
  {
     // 必须启动事务来修改文档
     if (TransactionStatus.Started == transaction.Start())
     {
        if (null != document.Create.NewLevel(elevation))
        {
           return (TransactionStatus.Committed == transaction.Commit());
        }
        // 如果不能创建层,撤销这个事务
        transaction.RollBack();
     }
  }
  return false;
}

public bool CreateGrid(Autodesk.Revit.DB.Document document, XYZ p1, XYZ p2)
{
  using (Transaction transaction = new Transaction(document, "Creating Grid"))
  {
     if (TransactionStatus.Started == transaction.Start())
     {
        Line gridLine = Line.CreateBound(p1, p2);

        if ((null != gridLine) && (null != document.Create.NewGrid(gridLine)))
        {
           if (TransactionStatus.Committed == transaction.Commit())
           {
              return true;
           }
        }
        // 如果不能创建网格,撤销这个事务
        transaction.RollBack();
     }
  }
  return false;
}

TransactionHandleCmd类功能为在同一位置绘制三堵墙,并在事务中使用自定义的故障处理选项,自定义的方式是把SameElementProcessor作为故障预处理器Set到故障处理选项中。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using TransactionHandleDemo;

namespace TransactionHandleCmd
{

    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    public class Class1 : IExternalCommand
    {
        //TransactionHandleCmd类功能为在同一位置绘制三堵墙,并在事务中使用自定义的故障处理选项
        //自定义的方式是把SameElementProcessor作为故障预处理器Set到故障处理选项中
        public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            try
            {
                Document doc = commandData.Application.ActiveUIDocument.Document;
                Transaction tran = new Transaction(doc);
                tran.Start("创建同名标高");
                //Returns the current failure handling options. 
                FailureHandlingOptions failureOptions = tran.GetFailureHandlingOptions();
                //Sets options for handling failures to be used when the transaction is being committed or rolled back. 
                failureOptions.SetFailuresPreprocessor(new SameElementProcessor());
                tran.SetFailureHandlingOptions(failureOptions);
                Line line = Line.CreateBound(XYZ.Zero, XYZ.BasisX * 5);
                Level level = getLevel(doc);
                Wall.Create(doc, line, level.Id, false);
                Wall.Create(doc, line, level.Id, false);
                Wall.Create(doc, line, level.Id, false);
                tran.Commit();
                return Autodesk.Revit.UI.Result.Succeeded;
            }
            catch (Exception ex)
            {
                message = ex.Message;
                return Autodesk.Revit.UI.Result.Failed;
            }
        }


        private Level getLevel(Document doc)
        {
            return (Level)new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels)
                 .OfClass(typeof(Level)).FirstElement();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
namespace TransactionHandleDemo
{
    //如果提供了该接口,则在事务结束时发现故障时调用该接口。可以在事务对象的失败处理选项中设置此接口的实例。
    public class SameElementProcessor : IFailuresPreprocessor
    {
        public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
        {
            failuresAccessor.DeleteAllWarnings();
            return FailureProcessingResult.Continue;
        }
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孤影墨客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值