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 time stamp walls during their creations in an External DB Application (IExternalDBApplication).
It is obvious that an IUpdater interface has to be implemented and registered in the OnStartup point as follows:
#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 ExtDbApp1 : 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");
Updater1 updater1 = new Updater1(_cachedCtrlApp.ActiveAddInId);
UpdaterRegistry.RegisterUpdater(updater1);
ElementCategoryFilter catFilter = new ElementCategoryFilter(Autodesk.Revit.DB.BuiltInCategory.OST_Walls);
UpdaterRegistry.AddTrigger(updater1.GetUpdaterId(), catFilter, Element.GetChangeTypeElementAddition());
return ExternalDBApplicationResult.Succeeded;
}
catch (Exception ex)
{
MessageBox.Show( ex.ToString() );
return ExternalDBApplicationResult.Failed;
}
}
public ExternalDBApplicationResult OnShutdown(ControlledApplication ctlApp)
{
try
{
UpdaterRegistry.UnregisterUpdater(new Updater1(ctlApp.ActiveAddInId).GetUpdaterId());
return ExternalDBApplicationResult.Succeeded;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return ExternalDBApplicationResult.Failed;
}
}
#endregion
}
}
Here is the implementation of the IUpdater interface:
using System;
using System.Text;
using System.Xml;
using System.Linq;
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;
namespace RevitAddinCS1
{
public class Updater1 : IUpdater
{
private AddInId mAddinId;
private UpdaterId mUpdaterId;
public Updater1(AddInId id)
{
mAddinId = id;
mUpdaterId = new UpdaterId(mAddinId, new Guid("e2365ea2-f1ee-459f-a1ec-8eee516f9408"));
}
#region IUpdater Members
public void Execute(UpdaterData updaterData)
{
Document doc = updaterData.GetDocument();
ICollection<ElementId> addedIds = updaterData.GetAddedElementIds();
using (SubTransaction tr = new SubTransaction(doc))
{
tr.Start();
foreach (ElementId id in addedIds)
{
Element element = doc.get_Element(id);
MyData data = new MyData
{
byteVar = 255,
charVar = 'a',
ushortVar = 65535,
longVar = 1234567890,
decimalVar = 1.123456789123456789M,
dateTimeVar = new DateTime(2012, 2, 14, 23, 59, 59)
};
RevitAddinWizard.SuperEasyCoolDataOperator.SetDataToElement("DA4AAE5A-4EE1-45A8-B3E8-F790C84CC44F", data, element);
}
tr.Commit();
}
}
public string GetAdditionalInformation()
{
return "Updater1";
}
public ChangePriority GetChangePriority()
{
return Autodesk.Revit.DB.ChangePriority.Annotations;
}
public UpdaterId GetUpdaterId()
{
return mUpdaterId;
}
public string GetUpdaterName()
{
return "Updater1";
}
#endregion
}
}
If the External DBApplication is properly registered in a Revit manifest file like this:
<AddIn Type="DBApplication">
<Assembly>C:\Temp\RevitAddinCS1\bin\Debug\RevitAddinCS1.dll</Assembly>
<FullClassName>RevitAddinCS1.ExtDbApp1</FullClassName>
<ClientId>5422d57c-7fd6-45e0-a4ba-e00180DB2012</ClientId>
<Name>RevitAddinCS1.ExtDbApp1</Name>
<VendorId>RAW</VendorId>
</AddIn>
When any new wall is being created, it will be time stamped along with some other example data. If the same SuperEasyCoolDataOperator is used to retrieve the same data from the wall, we will see things work just as expected.
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 the Element Updater wizard, the above code can be created conveniently in a minute.
Recent Comments