We talk about Revit Application and Document events in this article. People may wonder why we have to talk about the Application and Document events together since we have discussed about them respectively and demonstrated with both C# and VB.NET in a few existing posts.
The Revit Application and the Document classes provide some similar events such as DocumentClosing, DocumentPrinted, DocumentSaved, and ViewPrinted. The article will focus on these duplicates and try to answer whether it is necessary and good.
The Revit Document class provides nine events, one of which is document closing related, two of which are printing related, four of which are saving related, and two of which are view printing related:
DocumentClosing
DocumentPrinted
DocumentPrinting
DocumentSaved
DocumentSavedAs
DocumentSaving
DocumentSavingAs
ViewPrinted
ViewPrinting
It seems natural though as these activities are generally document involved. However the thing is that the Revit Application class also provides all the nine events:
DocumentClosing
DocumentPrinted
DocumentPrinting
DocumentSaved
DocumentSavedAs
DocumentSaving
DocumentSavingAs
ViewPrinted
ViewPrinting
besides some unique ones:
DocumentChanged
DocumentClosed
DocumentCreated
DocumentCreating
DocumentOpened
DocumentOpening
DocumentSynchronizedWithCentral
DocumentSynchronizingWithCentral
FailuresProcessing
FileExported
FileExporting
FileImported
FileImporting
Why is that? Is it really necessary?
Before answering the question, let’s do some experiments first. Supposing we have the following Application kind DocumentClosing and ViewPrinted event handlers:
Public Shared Sub ApplicationEvent_DocumentClosing_Handler(ByVal sender As Object, ByVal args As EventArgs)
Dim specificArgs As Autodesk.Revit.DB.Events.DocumentClosingEventArgs = TryCast(args, Autodesk.Revit.DB.Events.DocumentClosingEventArgs)
Dim msg As String = "Cancellable: " & specificArgs.Cancellable & vbCrLf & "Document Title: " & specificArgs.Document.Title & vbCrLf
MessageBox.Show(msg, "Application DocumentClosing Event")
End Sub
Public Shared Sub ApplicationEvent_ViewPrinted_Handler(ByVal sender As Object, ByVal args As EventArgs)
Dim specificArgs As Autodesk.Revit.DB.Events.ViewPrintedEventArgs = TryCast(args, Autodesk.Revit.DB.Events.ViewPrintedEventArgs)
Dim msg As String = "Cancellable: " & specificArgs.Cancellable & vbCrLf & "View Name: " & specificArgs.View.Name & vbCrLf
MessageBox.Show(msg, "Application ViewPrinted Event")
End Sub
And the following Document kind DocumentClosing and ViewPrinted event handlers:
Public Shared Sub DocEvent_DocumentClosing_Handler(ByVal sender As Object, ByVal args As EventArgs)
Dim specificArgs As Autodesk.Revit.DB.Events.DocumentClosingEventArgs = TryCast(args, Autodesk.Revit.DB.Events.DocumentClosingEventArgs)
Dim msg As String = "Cancellable: " & specificArgs.Cancellable & vbCrLf & "Document Title: " & specificArgs.Document.Title & vbCrLf
MessageBox.Show(msg, "Document DocumentClosing Event")
End Sub
Public Shared Sub DocEvent_ViewPrinted_Handler(ByVal sender As Object, ByVal args As EventArgs)
Dim specificArgs As Autodesk.Revit.DB.Events.ViewPrintedEventArgs = TryCast(args, Autodesk.Revit.DB.Events.ViewPrintedEventArgs)
Dim msg As String = "Cancellable: " & specificArgs.Cancellable & vbCrLf & "View Name: " & specificArgs.View.Name & vbCrLf
MessageBox.Show(msg, "Document ViewPrinted Event")
End Sub
and they are all properly registered. How will they behave in Revit?
We will observe that they behave the same except for a slight difference that all people can guess out, timing. The Application ones occur right after the Document ones. I would even say the timing is not really a difference at all as the message boxes have to appear one by one anyway.
In addition, as can be seen, the event argument types and their properties are exactly the same. So we can safely reach the conclusion. The pair events use the same internal stuffs or one is forwarded the call to another no matter where they are, in the Application or the Document.
Experiments haven’t been done to the other seven events, but it would not be surprising at all if other pairs also behave the same and have the same event argument types and properties.
People may wonder again then why duplicate events are put into different places. Good question!
The real concern however seems what the Application should really care about and what the Document should do as far as events are concerned.
Personally, those document closing/closed, printing/printed, and saving/saved things should be looked after by the Application object. They actually are in the Revit product, aren’t they? Say, what will happen if users click the X button of the Application window? The Revit Application will close all those opened documents one by one and ask whether to save it if modifications not saved, right? And printing seems also an Application wide thing. It is rare that a document really concerns about whether itself is being printed or not. I may be wrong.
In terms of the ViewPrinting and ViewPrinted events, things seem quite arguable, whether they are Document focused, Application wide, or even UIApplication relevant as the ViewActivating and ViewActivated events are. Things are pretty touch, eh?
Let’s look at another event of the Application object and it is not available in the Document object.
Public Shared Sub ApplicationEvent_DocumentClosed_Handler(ByVal sender As Object, ByVal args As EventArgs)
Dim specificArgs As Autodesk.Revit.DB.Events.DocumentClosedEventArgs = TryCast(args, Autodesk.Revit.DB.Events.DocumentClosedEventArgs)
Dim msg As String = "Cancellable: " & specificArgs.Cancellable & vbCrLf & "Document Title: " & specificArgs.DocumentId & vbCrLf
MessageBox.Show(msg, "Application DocumentClosed Event")
End Sub
If it is properly registered we will observe that the notification will be sent when a Document has been closed. So the DocumentClosed event is in the right place, the Application object, and behaves just well. It makes sense that it is not in the Document object as at that moment the whole document has already been destroyed so does not have a spot for the event.
Ok. Now let’s look at one more event of the Application object and it is not available in the Document object either.
Public Shared Sub ApplicationEvent_DocumentChanged_Handler(ByVal sender As Object, ByVal args As EventArgs)
Dim specificArgs As Autodesk.Revit.DB.Events.DocumentChangedEventArgs = TryCast(args, Autodesk.Revit.DB.Events.DocumentChangedEventArgs)
Dim msg As String = "Cancellable: " & specificArgs.IsCancellable & vbCrLf & "Document Title: " & specificArgs.GetDocument().Title & vbCrLf
MessageBox.Show(msg, "Application DocumentChanged Event")
End Sub
From the name and home of the event, I got the impression that the event would be fired when a Document is changed from one to another through the Switch Windows buttons or commands for example. What else would people expect if not so?
However, the experiment result was really out of my expectations, and out of yours as well, I believe. When I switched a document, the DocumentChanged event of the Application object was not notified at all. However, when a new document was created or an element was added or modified in the current document, the event was sent out. By checking on the DocumentChangedEventArgs in detail I figured that the event is put at a wrong place and given a wrong name. It would make sense if the event were put into the Document object and named as ElementChanged or something like that. By the way, the DocumentChangedEventArgs has the following properties:
GetAddedElementIds
GetDeletedElementIds
GetModifiedElementIds
GetTransactionNames
So it looks like the DocumentChanged event can be used as an alternative to the IUpdater that we talked about and demonstrated before. If having interest, please have a look at them from this perspective.
Experiments haven’t been done to other Application or Document events on my side. Once again, if you are interested in, please give them a try. Something else will be found out, I believe. Have fun!
RevitAddinWizard can help create Revit Addin Projects in C#, VB.NET, or CLI/C++ and Application/Document even handlers automatically in no time.
Recent Comments