The IUpdater interface of Revit API provides a means to monitor element status such as addition, deletion, and modification.
The IUpdater has a few methods for derivatives to implement, for example, Execute, GetAdditionalInformation, GetChangePriority, GetUpdaterId, and GetUpdaterName.
The core method is the Execute(). It offers an UpdaterData parameter which provides information about elements just added, deleted, or modified in a document.
An UpdaterId instance needs to be created and returned from the GetUpdaterId() method. The GetChangePriority() method tells Revit what the priority is to call this updater comparing to others. The basic idea is more generic higher priority.
The following code monitors additions and deletions of elements:
public class ElementUpdater1 : IUpdater
{
private AddInId mAddinId;
private UpdaterId mUpdaterId;
public ElementUpdater1(AddInId id)
{
mAddinId = id;
mUpdaterId = new UpdaterId(mAddinId, new Guid("69c641d9-c838-42bb-983f-d30b8d01d4bb"));
}
#region IUpdater Members
public void Execute(UpdaterData data)
{
Document doc = data.GetDocument();
ICollection<ElementId> addedIds = data.GetAddedElementIds();
foreach (ElementId id in addedIds)
{
Element elem = doc.get_Element(id);
MessageBox.Show(string.Format("{0}({1}) has been added.", elem.Name, id.IntegerValue));
}
ICollection<ElementId> deletedIds = data.GetDeletedElementIds();
foreach (ElementId id in deletedIds)
{
MessageBox.Show(string.Format("{0} has been deleted.", id.IntegerValue));
}
}
public string GetAdditionalInformation()
{
return "ElementUpdater1";
}
public ChangePriority GetChangePriority()
{
return Autodesk.Revit.DB.ChangePriority.FloorsRoofsStructuralWalls;
}
public UpdaterId GetUpdaterId()
{
return mUpdaterId;
}
public string GetUpdaterName()
{
return "ElementUpdater1";
}
#endregion
}
The following code registers the updater against Walls and adds triggers of element addition and deletion in the OnStartup event of an external application:
// Register the ElementUpdater1
ElementUpdater1 updater1 = new ElementUpdater1(uiApp.ActiveAddInId);
UpdaterRegistry.RegisterUpdater(updater1);
ElementCategoryFilter catFilter = new ElementCategoryFilter(Autodesk.Revit.DB.BuiltInCategory.OST_Walls);
UpdaterRegistry.AddTrigger(updater1.GetUpdaterId(), catFilter, Element.GetChangeTypeElementAddition());
UpdaterRegistry.AddTrigger(updater1.GetUpdaterId(), catFilter, Element.GetChangeTypeElementDeletion());
The following code unregisters the updater in the OnShutdown event of the same external application:
// Unregister the ElementUpdater1
UpdaterRegistry.UnregisterUpdater(new ElementUpdater1(uiApp.ActiveAddInId).GetUpdaterId());
All the above code can be created automatically by the Element Updater of the RevitAddinWizard through a few clicks.
Links to some related articles:
Use RevitAddinWizard to Create IUpdater Derivatives of Revit API
Implement IFailuresPreprocessor of Revit API
Use RevitAddinWizard to Implement IFailuresPreprocessor of Revit API
Implement An IFailuresProcessor of Revit API
Use RevitAddinWizard to Implement IFailuresProcessor of Revit API
Command Availability And Revit Flavors/Categories of Revit API
Use RevitAddinWizard to Implement IExternalCommandavailability of Revit API
Implement ISelectionFilter of Revit API
Use RevitAddinWizard to Implement ISelectionFilter of Revit API
a vb.net version would be very helpful. I'm getting
"...must implement 'Sub Execute(data As UpdaterData)' for interface 'Autodesk.Revit.DB.IUpdater"
But I don't know how to resolve it. (yet)
Posted by: Gregory Mertens | 05/09/2013 at 04:25 PM
ah....color me new.
http://spiderinnet.typepad.com/blog/2011/06/revit-api-vbnet-iupdater-implementation-with-vbnet.html
Posted by: Gregory Mertens | 05/09/2013 at 04:30 PM
Glad you found out the clue yourself.
It seems you used some online free code converter to do the conversion automatically. If so, many times, it may not be a very pleasant experience, as discussed in a few recent posts. Here is one:
http://spiderinnet.typepad.com/blog/2013/04/another-simple-case-c-to-vbnet-converter-cannot-address-properly.html
Anyway, if any other questions, please feel free to throw them in.
Posted by: Spiderinnet | 05/09/2013 at 08:36 PM
That's exactly what I did. Most of the time the conversions work out well. Still learning though.
Posted by: Gregory Mertens | 05/10/2013 at 02:09 PM
Right, they work fine for common and simple situations. In your case, the converter cannot know which method is the override one in C# but VB.NET needs different syntax for those methods.
Posted by: Spiderinnet | 05/10/2013 at 02:16 PM
Hi, I'm trying to understand how to implement an IUpdater using Element.GetChangeTypeParameter() method with a project parameter/shared parameter. I need to be able to input the parameter or id but can't seem to get the Document instance in the OnStartup method. Essentially what I am trying to do is keep a shared parameter updated from a project parameter. It works fine with the Element.GetChangeTypeAny() method. How would you specify the parameter in the OnStartup method? Thanks.
Posted by: Michael Coffey | 10/30/2013 at 01:00 PM
Using the IExternalDBApplication and some Document events seem what you are looking for. An old post demonstrated something about it:
Revit API 2012: Create Something at Startup of External DB Application (IExternalDBApplication)
http://spiderinnet.typepad.com/blog/2012/02/revit-api-2012-create-something-at-startup-of-external-db-application-iexternaldbapplication.html
If each document has to be monitored for the parameter change, some other existing posts may help.
Manage document events of Revit API with C# - Part 1
http://spiderinnet.typepad.com/blog/2011/02/manage-document-events-of-revit-api-with-c-part-1.html
Manage document events of Revit API with C# - Part 2
http://spiderinnet.typepad.com/blog/2011/02/manage-document-events-of-revit-api-with-c-part-2.html
Manage document events of Revit API with C# - Part 3
http://spiderinnet.typepad.com/blog/2011/02/manage-document-events-of-revit-api-with-c-part-3.html
Posted by: Spiderinnet | 10/30/2013 at 04:48 PM