Revit API 2012 provides one more application type, IExternalDBApplication, which is supposed to help do some DB stuffs at Revit startup, monitor some document events, and so on. In this post, we are going to see how to keep records of the status of elements in an External DB Application (IExternalDBApplication).
It is obvious that the DocumentChanged and needs to be listened to in the OnStartup point as follows:
_cachedCtrlApp.DocumentChanged += new EventHandler<DocumentChangedEventArgs>(_cachedCtrlApp_DocumentChanged);
Then we can implement the event handler like:
void _cachedCtrlApp_DocumentChanged(object sender, DocumentChangedEventArgs e)
{
try
{
ICollection<ElementId> ids = e.GetAddedElementIds();
foreach (ElementId id in ids)
{
using (StreamWriter sw = new StreamWriter(@"c:\temp\RevitElements.txt", true))
{
sw.WriteLine(DateTime.Now.ToString() + " : The element with #" + id.ToString() + " was added.");
}
}
ids = e.GetDeletedElementIds();
foreach (ElementId id in ids)
{
using (StreamWriter sw = new StreamWriter(@"c:\temp\RevitElements.txt", true))
{
sw.WriteLine(DateTime.Now.ToString() + " : The element with #" + id.ToString() + " was deleted.");
}
}
ids = e.GetModifiedElementIds();
foreach (ElementId id in ids)
{
using (StreamWriter sw = new StreamWriter(@"c:\temp\RevitElements.txt", true))
{
sw.WriteLine(DateTime.Now.ToString() + " : The element with #" + id.ToString() + " was modified.");
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Then whenever an element is added, changed, or deleted, a record will be added to the log file. Here is an example of such a log file:
2012-03-04 10:00:44 PM : The element with #3313 was added.
2012-03-04 10:01:01 PM : The element with #3330 was added.
2012-03-04 10:01:01 PM : The element with #3313 was modified.
2012-03-04 10:01:03 PM : The element with #3349 was added.
2012-03-04 10:01:03 PM : The element with #3313 was modified.
2012-03-04 10:01:04 PM : The element with #3367 was added.
2012-03-04 10:01:04 PM : The element with #3313 was modified.
2012-03-04 10:01:14 PM : The element with #3118 was deleted.
2012-03-04 10:01:14 PM : The element with #1912 was modified.
2012-03-04 10:01:18 PM : The element with #3133 was deleted.
2012-03-04 10:01:18 PM : The element with #1912 was modified.
2012-03-04 10:01:25 PM : The element with #3409 was added.
2012-03-04 10:01:25 PM : The element with #2527 was deleted.
2012-03-04 10:01:25 PM : The element with #1912 was modified.
2012-03-04 10:01:25 PM : The element with #2512 was modified.
2012-03-04 10:01:38 PM : The element with #1912 was modified.
2012-03-04 10:01:38 PM : The element with #2512 was modified.
2012-03-04 10:01:47 PM : The element with #1912 was modified.
2012-03-04 10:01:47 PM : The element with #2512 was modified.
2012-03-04 10:01:55 PM : The element with #3448 was added.
2012-03-04 10:01:55 PM : The element with #1912 was modified.
Here is the whole implementation of the IExternalDBApplication for convenience:
#region Namespaces
using System;
using System.Text;
using System.Linq;
using System.Xml;
using System.Reflection;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Forms;
using System.IO;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.UI.Events;
using Autodesk.Revit.Collections;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.Utility;
using RvtApplication = Autodesk.Revit.ApplicationServices.Application;
using RvtDocument = Autodesk.Revit.DB.Document;
#endregion
namespace RevitAddinCS1
{
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
public class ExtDbApp : IExternalDBApplication
{
#region Cached Variables
public static ControlledApplication _cachedCtrlApp;
#endregion
#region IExternalApplication Members
public ExternalDBApplicationResult OnStartup(ControlledApplication ctrlApp)
{
try
{
_cachedCtrlApp = ctrlApp;
//TODO: add you code below.
//MessageBox.Show("ExtDbApp");
_cachedCtrlApp.DocumentCreated += new EventHandler<DocumentCreatedEventArgs>(_cachedCtrlApp_DocumentCreated);
_cachedCtrlApp.DocumentOpened += new EventHandler<DocumentOpenedEventArgs>(_cachedCtrlApp_DocumentOpened);
_cachedCtrlApp.DocumentClosed += new EventHandler<DocumentClosedEventArgs>(_cachedCtrlApp_DocumentClosed);
_cachedCtrlApp.DocumentSaving += new EventHandler<DocumentSavingEventArgs>(_cachedCtrlApp_DocumentSaving);
_cachedCtrlApp.DocumentSavingAs += new EventHandler<DocumentSavingAsEventArgs>(_cachedCtrlApp_DocumentSavingAs);
_cachedCtrlApp.DocumentClosing += new EventHandler<DocumentClosingEventArgs>(_cachedCtrlApp_DocumentClosing);
_cachedCtrlApp.DocumentChanged += new EventHandler<DocumentChangedEventArgs>(_cachedCtrlApp_DocumentChanged);
return ExternalDBApplicationResult.Succeeded;
}
catch (Exception ex)
{
MessageBox.Show( ex.ToString() );
return ExternalDBApplicationResult.Failed;
}
}
void _cachedCtrlApp_DocumentChanged(object sender, DocumentChangedEventArgs e)
{
try
{
ICollection<ElementId> ids = e.GetAddedElementIds();
foreach (ElementId id in ids)
{
using (StreamWriter sw = new StreamWriter(@"c:\temp\RevitElements.txt", true))
{
sw.WriteLine(DateTime.Now.ToString() + " : The element with #" + id.ToString() + " was added.");
}
}
ids = e.GetDeletedElementIds();
foreach (ElementId id in ids)
{
using (StreamWriter sw = new StreamWriter(@"c:\temp\RevitElements.txt", true))
{
sw.WriteLine(DateTime.Now.ToString() + " : The element with #" + id.ToString() + " was deleted.");
}
}
ids = e.GetModifiedElementIds();
foreach (ElementId id in ids)
{
using (StreamWriter sw = new StreamWriter(@"c:\temp\RevitElements.txt", true))
{
sw.WriteLine(DateTime.Now.ToString() + " : The element with #" + id.ToString() + " was modified.");
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
void _cachedCtrlApp_DocumentClosing(object sender, DocumentClosingEventArgs e)
{
if (e.Cancellable)
{
MessageBox.Show("Document cannot be closed!");
e.Cancel();
}
}
void _cachedCtrlApp_DocumentSavingAs(object sender, DocumentSavingAsEventArgs e)
{
if (e.Cancellable && e.Document.PathName.ToLower() == "c:\\temp\\cannotsave.rvt")
{
MessageBox.Show("The model cannot be saved!");
e.Cancel();
}
}
void _cachedCtrlApp_DocumentSaving(object sender, DocumentSavingEventArgs e)
{
if (e.Cancellable && e.Document.PathName.ToLower() == "c:\\temp\\cannotsave.rvt")
{
MessageBox.Show("The model cannot be saved!");
e.Cancel();
}
}
void _cachedCtrlApp_DocumentClosed(object sender, DocumentClosedEventArgs e)
{
using (StreamWriter sw = new StreamWriter(@"c:\temp\RevitLogOpenClose.txt", true))
{
sw.WriteLine(DateTime.Now.ToString() + " : The document with #" + e.DocumentId.ToString() + " was closed.");
}
}
void _cachedCtrlApp_DocumentOpened(object sender, DocumentOpenedEventArgs e)
{
using (StreamWriter sw = new StreamWriter(@"c:\temp\RevitLogOpenClose.txt", true))
{
sw.WriteLine(DateTime.Now.ToString() + " : The document " + e.Document.PathName + " was opened.");
}
}
void _cachedCtrlApp_DocumentCreated(object sender, DocumentCreatedEventArgs e)
{
Document doc = e.Document;
ElementId id = ElementId.InvalidElementId;
using (Transaction tr = new Transaction(doc, "Hello from RevitAddinWizard."))
{
tr.Start();
TextNote text = doc.Create.NewTextNote(
doc.ActiveView,
new XYZ(0, 0, 0),
new XYZ(1, 0, 0),
new XYZ(0, 0, 1),
2,
TextAlignFlags.TEF_ALIGN_CENTER,
"Hello from RevitAddinWizard.");
text.Width = 20;
tr.Commit();
id = text.Id;
}
}
public ExternalDBApplicationResult OnShutdown(ControlledApplication ctlApp)
{
try
{
return ExternalDBApplicationResult.Succeeded;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return ExternalDBApplicationResult.Failed;
}
}
#endregion
}
}
Revit Addin Wizard (RevitAddinWizard) is going to provide an External DB Application wizard to help implement the IExternalDBApplication interface automatically and reliably. With the assistance of the External DB Application wizard and some event wizards, the above code can be created conveniently in a minute.
Recent Comments