事件

事件是在Revit用户界面或API工作流中执行特定操作时触发的通知。通过订阅事件,可以在操作即将发生或刚刚发生时通知外接程序应用程序,并采取与该事件相关的某些操作。有些事件是成对发生的,一个发生在动作发生之前(“pre”事件),另一个发生在动作发生之后(“post”事件)。在这些前/后对中不发生的事件称为“单个”事件。

Revit提供对应用程序级别(如ApplicationClosing或DocumentOpened)和文档级别(如DocumentClosing和DocumentPrinting)的事件的访问。Application类中提供的相同应用程序级别事件也可从ControlledApplication类中获得,ControlledApplication类表示未访问文档的Revit应用程序。ControlledApplication可用于OnStartup()和OnStartup()方法中的外接程序。就订阅和取消订阅事件而言,这些类是可互换的;从ControlledApplication类订阅事件与从Application类订阅事件相同。

事件还可以分类为数据库(DB)事件或用户界面(UI)事件。DB事件可从Application和Document类获得,而UI事件可从UIApplication类获得。(目前所有UI事件都仅在应用程序级别)。

有些事件被认为是只读的,这意味着在它们的执行过程中,模型可能不会被修改。事件为只读的事实在API帮助文件中有说明。重要的是要知道,即使在常规事件(即非只读事件)期间,模型也可能处于无法修改的状态。程序员应该检查属性Document.IsModifiable和Document.IsReadOnly以确定模型是否可以修改。

本节中的页面

  • 数据库事件
  • 用户界面事件
  • 注册事件
  • 取消事件

数据库事件

下表列出了数据库事件、它们的类型以及它们是否在应用程序和/或文档级别可用:

表53:数据库事件类型

Event 事件 Type 类型 Application 应用 Document 文档
DocumentChanged event single X
DocumentClosing pre X X
DocumentClosed post X
DocumentCreating pre X
DocumentCreated post X
DocumentOpening pre X
DocumentOpened post X
DocumentPrinting pre X X
DocumentPrinted post X X
DocumentSaving pre X X
DocumentSaved post X X
DocumentSavingAs pre X X
DocumentSavedAs post X X
DocumentSynchronizingWithCentral pre X
DocumentSynchronizedWithCentral post X
FailuresProcessing single X
FileExporting pre X
FileExported post X
FileImporting pre X
FileImported post X
ProgressChanged single X
ViewPrinting pre X X
ViewPrinted post X X
  • DocumentChanged -提交、撤消或重做事务时的通知
  • DocumentClosing -Revit即将关闭文档时的通知
  • DocumentClosed -Revit关闭文档后立即发出的通知
  • DocumentCreating -Revit将要创建新文档时的通知
  • DocumentCreated -Revit完成创建新文档时的通知
  • DocumentOpening -Revit即将打开文档时的通知
  • DocumentOpened -Revit打开文档后的通知
  • DocumentPrinting -Revit将要打印文档的视图或视图集时的通知
  • DocumentPrinted -在Revit打印完文档的视图或视图集后发出的通知
  • DocumentSaving -Revit即将保存文档时的通知
  • DocumentSaved -Revit保存文档后立即发出的通知
  • DocumentSavingAs -Revit将以新名称保存文档时的通知
  • DocumentSavedAs -当Revit刚用新名称保存文档时发出的通知
  • DocumentSynchronizingWithCentral -当Revit要将文档与中心文件同步时发出的通知
  • DocumentSynchronizedWithCentral -在Revit将文档与中心文件同步后发出的通知
  • FailuresProcessing -事务结束时Revit处理失败时的通知
  • FileExporting -Revit即将导出为API支持的文件格式时的通知
  • FileExported -Revit导出为API支持的文件格式后的通知
  • FileImporting -Revit将要导入API支持的文件格式时的通知
  • FileImported -Revit导入API支持的文件格式后的通知
  • ProgressChanged -当Revit中的操作具有进度条数据时发出的通知
  • ViewPrinting -Revit即将打印文档视图时的通知
  • ViewPrinted -在Revit打印完文档视图后立即发出通知

本节中的页面

  • DocumentChanged事件

DocumentChanged事件

更改Revit文档时会触发DocumentChanged事件。只要提交、撤消或重做Revit事务,就会引发此事件。这是一个只读事件,旨在允许外部数据与Revit数据库的状态保持同步。若要更新Revit数据库以响应图元中的更改,请使用IUpdater框架。

DocumentChangedEventArgs类由DocumentChanged事件使用。这个类有几个方法来获取任何新添加的元素(GetAddElementIds())、已删除的元素(GetDeletedElementIds())或已修改的元素(GetModifiedElementIds())的元素ID。GetAddElementIds()和GetModifiedElementIds()方法具有采用ElementFilter的重载,这使得仅检测感兴趣的更改变得容易。

用户界面事件

下表列出了用户界面事件、它们的类型以及它们是否在应用程序和/或文档级别可用:

表54:UI事件类型

**Event ** **Type ** UIApplication **ControlledApplication ** **UIDocument **
ApplicationClosing pre X
ApplicationInitialized single X
DialogBoxShowing single X
DisplayingOptionsDialog single X
Idling single X
ViewActivating pre X
ViewActivated post X
  • ApplicationClosing - 即将关闭Revit应用程序时的通知
  • ApplicationInitialized-在Revit应用程序初始化后、所有外部应用程序已启动且应用程序已准备好处理文档后发出的通知
  • DialogBoxShowing-Revit显示对话框或消息框时的通知
  • DisplayingOptionsDialog -显示Revit选项对话框时的通知
  • Idling - Revit不在活动工具或事务中时的通知
  • ViewActivating -Revit即将激活文档视图时的通知
  • ViewActivated -在Revit激活文档视图后立即发出通知

注册事件

在哪里以及如何注册事件。

使用事件是一个两步的过程。首先,必须有一个处理事件通知的函数。这个函数必须接受两个参数,第一个是Object,表示事件通知的“发送者”,第二个是事件特定的对象,包含特定于该事件的事件参数。例如,若要注册DocumentSavingAs事件,事件处理程序必须采用第二个参数,该参数是DocumentSavingAsEventArgs对象。

使用事件的第二部分是向Revit注册事件。这可以在OnStartup()函数中通过ControlledApplication参数完成,也可以在Revit启动后的任何时间完成。虽然可以为外部命令和外部应用程序注册事件,但不建议这样做,除非外部命令在同一外部命令中注册和取消注册事件。还要注意,注册到事件和从事件取消注册必须在主线程上执行时发生。如果外部应用程序试图从有效的API上下文外部注册事件(或取消注册),则将引发异常。

下面的示例注册DocumentOpened事件,当触发该事件时,此应用程序将设置项目的地址。

代码区域24-1:注册ControlledApplication.DocumentOpened

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class Application_DocumentOpened : IExternalApplication
{
///
///
/// Implement this method to subscribe to event.
///
public Result OnStartup(UIControlledApplication application)
{
try
{
// Register event.
application.ControlledApplication.DocumentOpened += new EventHandler
<Autodesk.Revit.DB.Events.DocumentOpenedEventArgs>(application_DocumentOpened);
}
catch (Exception)
{
return Result.Failed;
}

return Result.Succeeded;
}

public Result OnShutdown(UIControlledApplication application)
{
// remove the event.
application.ControlledApplication.DocumentOpened -= application_DocumentOpened;
return Result.Succeeded;
}

public void application_DocumentOpened(object sender, DocumentOpenedEventArgs args)
{
// get document from event args.
Document doc = args.Document;

// Following code snippet demonstrates support of DocumentOpened event to modify the model.
// Because DocumentOpened supports model changes, it allows user to update document data.
// Here, this sample assigns a specified value to ProjectInformation.Address property.
// User can change other properties of document or create(delete) something as he likes.
//
// Please note that ProjectInformation property is empty for family document.
// So please don't run this sample on family document.
using (Transaction transaction = new Transaction(doc, "Edit Address"))
{
if (transaction.Start() == TransactionStatus.Started)
{
doc.ProjectInformation.Address =
"United States - Massachusetts - Waltham - 1560 Trapelo Road";
transaction.Commit();
}
}
}
}

取消事件

在操作发生之前触发的事件(即DocumentSaving)通常是可取消的。(用可取消属性,以确定事件是否可以取消。)例如,您可能希望在保存模型之前检查模型是否满足某些条件。例如,通过注册DocumentSaving或DocumentSavingAs事件,您可以检查文档中的某些条件并取消Save或Save As操作。事件一旦取消,就无法取消。

注意:如果取消了pre事件,则不会通知已订阅该事件的其他事件处理程序。但是,将通知已订阅与前事件相关的后事件的处理程序。下面的DocumentSavingAs事件的事件处理程序检查ProjectInformation Status参数是否为空,如果为空,则取消SaveAs事件。请注意,如果应用程序取消了一个事件,它应该向用户提供一个解释。

代码区域24-2:取消事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void CheckProjectStatusInitial(Object sender, DocumentSavingAsEventArgs args)
{
Document doc = args.Document;
ProjectInfo proInfo = doc.ProjectInformation;

// Project information is only available for project document.
if (null != proInfo)
{
if (string.IsNullOrEmpty(proInfo.Status))
{

// cancel the save as process.
args.Cancel = true;
MessageBox.Show("Status project parameter is not set. Save is aborted.");
}
}
}

注意:虽然大多数事件参数都有Cancel和Cancellable属性,但DocumentChanged和FailuresProcessing事件有相应的Cancel()和IsCancellable()方法。

注:翻译自Revit API Developers Guide