The workflow I had in mind was to use DMU registered at Document level. I wrote up this quick sample to illustrate the workflow I had in mind. If there is no element which contains the same project parameter, this code will not register the DMU itself.
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace Revit.SDK.Samples.HelloRevit.CS
{
[Transaction(TransactionMode.Manual)]
publicclassCommand : IExternalCommand
{
publicResult Execute(ExternalCommandData commandData,
refstring message,
ElementSet elements)
{
UIApplication uiApp = commandData.Application;
Document doc = uiApp.ActiveUIDocument.Document;
// Assuming the Project Parameter and the Category that it
// is associated with is known.
// For simplicity, this sample assumes that the project parameter
// is called Adsk and it is bound to Door category.
// Approach 1:
// Since the intention is to track the change of value of
// Project Parameters, it is being assumed that an instance
// which uses the project parameter already exists in the model.
// If it does not exist, the DMU will not be registered
FilteredElementCollector coll = newFilteredElementCollector(doc);
coll.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_Doors);
Element ele = coll.ToElements().First() asElement;
FamilyInstance door = ele asFamilyInstance;
if (null != door)
{
if (null != door.get_Parameter("Adsk"))
{
DoorParamUpdater doorUpdater = newDoorParamUpdater(uiApp.ActiveAddInId);
UpdaterRegistry.RegisterUpdater(doorUpdater);
ElementClassFilter wallFilter = newElementClassFilter(typeof(FamilyInstance));
UpdaterRegistry.AddTrigger(doorUpdater.GetUpdaterId(), wallFilter, Element.GetChangeTypeParameter(door.get_Parameter("Adsk")));
}
}
returnResult.Succeeded;
}
}
publicclassDoorParamUpdater : IUpdater
{
UpdaterId m_updaterId = null;
publicvoid Execute(UpdaterData data)
{
TaskDialog.Show("Hi", "You changed something!");
}
publicstring GetAdditionalInformation()
{
return"DoorParam updater checks any change in Project Param value";
}
publicChangePriority GetChangePriority()
{
returnChangePriority.DoorsOpeningsWindows;
}
publicUpdaterId GetUpdaterId()
{
return m_updaterId;
}
publicstring GetUpdaterName()
{
return"ProjectParameter Updater";
}
public DoorParamUpdater(AddInId id)
{
m_updaterId = newUpdaterId(id, newGuid("EF43510F-38CB-4980-844C-72174A674D56"));
}
}
To test this, create a RVT with a door instance and create a project parameter called Adsk and bind it to Door category. Clicking on the external command should register the DMU and any subsequent change in value of the project parameter should trap this. If the model does not contain the instance of the category or does not contain the project parameter you are looking for, the code will not register DMU for that model.
The other alternative to this approach is what has been mentioned by Revitalizer above.
I hope either of the approachs will help achieve your requirement.