- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Morning All,
I've worked my way through the forum enough to observe that a lot of development bug fix tickets come from these specific IUpdater issues, so I thought I would throw mine out here. Someone posted here with an identical issue back in 2015, but there was no solution found at that time.
I need to be able to watch the parameters of a load (both line loads and point loads) and trigger an IUpdater Execute() when the parameters are changed. The implementation is really quite simple and works beautifully for all instance parameters EXCEPT "Load Case" and "Is Reaction".
Changes to these two parameters do not trigger under any conditions I've been able to think of. Even the old tried-and-true solution of GetChangeTypeAny() does not trigger.
For convenience, I've included my reproducible test case right here. The actual updater is painfully simple:
public class LoadChangedUpdater : IUpdater
{
static AddInId m_appId;
static UpdaterId m_updaterId;
static UIControlledApplication application;
public LoadChangedUpdater(AddInId id, UIControlledApplication myApplication)
{
m_appId = id;
application = myApplication;
m_updaterId = new UpdaterId(m_appId, new Guid("4b0dda0f-1448-4bee-a6ca-519112d25d26"));
}
public void Execute(UpdaterData data)
{
//Simple pop-up if change is detected
MessageBox.Show("A load parameter change was detected!");
}
public string GetAdditionalInformation()
{
return "Load change: Generate a MessageBox if a load parameter is changed";
}
public ChangePriority GetChangePriority()
{
//I'm not 100% sure which ChangePriority is most appropriate here
return ChangePriority.FloorsRoofsStructuralWalls;
}
public UpdaterId GetUpdaterId()
{
return m_updaterId;
}
public string GetUpdaterName()
{
return "Load Change Updater";
}
}
The registry and trigger creation is handled in the OnStartup method for the application. Here is the registry and trigger which executes successfully for all EXCEPT the two I mentioned above. The filter captures only loads and the triggers use GetChangeTypeParameter()
//Build filters
ElementCategoryFilter myLineLoadFilter
= new ElementCategoryFilter(BuiltInCategory.OST_LineLoads);
ElementCategoryFilter myPointLoadFilter
= new ElementCategoryFilter(BuiltInCategory.OST_PointLoads);
LogicalOrFilter combinedLoadFilter
= new LogicalOrFilter(myLineLoadFilter, myPointLoadFilter);
//Register the updater
LoadChangedUpdater myLoadChangedUpdater
= new LoadChangedUpdater(application.ActiveAddInId, application);
UpdaterRegistry.RegisterUpdater(myLoadChangedUpdater);
//Iterate over all values in BuiltInParameter enum and add a trigger for each
foreach (BuiltInParameter myParam in BuiltInParameter.GetValues(typeof(BuiltInParameter)))
{
ElementId paramID = new ElementId(myParam);
UpdaterRegistry.AddTrigger(myLoadChangedUpdater.GetUpdaterId(),
combinedLoadFilter,
Element.GetChangeTypeParameter(paramID));
}
Now in the 2015 forum discussion on this topic, Arnost Lobel recommended testing with a fully generalized approach where the filter is set to capture all possible elements and the trigger uses GetChangeTypeAny(). Unfortunately, his example using an ExclusionFilter with an empty List<ElementId> throws an "ArgumentException". My alternative to this is simply to build a LogicalOrFilter to include all contents of the BuiltInCategory enum, which should essentially capture all possible elements. Coupling this with GetChangeTypeAny() produces identical behavior to the other test case. It successfully raises the updater Execute() method for all load parameters except "Load Case" and "Is Reaction". Here is that code sample:
// Register the updater
LoadChangedUpdater myLoadChangedUpdater
= new LoadChangedUpdater(application.ActiveAddInId, application);
UpdaterRegistry.RegisterUpdater(myLoadChangedUpdater);
//Declare filter list
IList<ElementFilter> allBuiltInCatsFilters = new List<ElementFilter>();
//Iterate over all values in BuiltInCategory enum and create a filter for each
foreach (BuiltInCategory myCat in BuiltInCategory.GetValues(typeof(BuiltInCategory)))
{
try
{
ElementCategoryFilter myFilter = new ElementCategoryFilter(myCat);
allBuiltInCatsFilters.Add(myFilter);
}
catch
{
}
}
LogicalOrFilter combinedCatsFilter = new LogicalOrFilter(allBuiltInCatsFilters);
UpdaterRegistry.AddTrigger(myLoadChangedUpdater.GetUpdaterId(),
combinedCatsFilter,
Element.GetChangeTypeAny());
I'm all ears if someone has already conquered this issue. Or I'm perfectly happy to help with whatever info is needed for a bug fix reproducible test case if needed.
Solved! Go to Solution.