Thursday, February 3, 2011

[Revit API]–Common Mistakes: DocumentSaved and DocumentSavedAs events

The Revit API has many useful events, including:

  • DocumentChanged
  • DocumentSaving
  • DocumentSavedAs
  • DocumentClosing
  • DocumentClosed
  • DocumentOpened
  • DocumentCreating
  • DocumentCreated
  • DocumentSynchronizingWithCentral
  • FileExported

And more. These let you run some code when certain events occur in Revit. You can make some powerful things with these events, so if you haven’t used them before, I recommend that you check them out.

A bit of a ‘duh’ moment that you may run into, is when you want to make a tool that runs whenever the user saves the document. Seems simple enough, you subscribe to the DocumentSaved event with code similar to this:

      public Result OnStartup(UIControlledApplication application)
        {
            application.ControlledApplication.DocumentSaved += ControlledApplication_DocumentSaved;
            return Result.Succeeded;
        }

However there’s a problem with this code – it won’t run the first time a user saves the document. This is because the DocumentSaved event is for when the user does a ‘Save’. If the document is new, when they click the save button, what Revit is actually doing in the background is a ‘Save As’, which prompts the user for a location and filename.

So, to get that event included as well you need to do something like this:

   public Result OnStartup(UIControlledApplication application)
        {
            application.ControlledApplication.DocumentSaved += ControlledApplication_DocumentSaved;
            application.ControlledApplication.DocumentSavedAs += ControlledApplication_DocumentSaved;

            return Result.Succeeded;
        }

This is registering the ControlledApplication_DocumentSaved method as a method to call when either of those events are called. To allow your save method to be the same method for each event, you need to set its parameters to be the following:

        void ControlledApplication_DocumentSaved(object sender, Autodesk.Revit.DB.Events.PostDocEventArgs e)
        {
          //my code goes here 
        }

Notice here that we are accepting event arguments of ‘PostDocEventArgs’ as opposed to ‘DocumentSavedAsEventArgs’ or ‘DocumentSavedEventArgs’, as PostDocEventArgs is a base class of these two.

Just something to keep in mind if you plan to use Revit’s powerful events API.

No comments: