I would like to create a dynamic model updater and set a trigger for the modify updater. I ‘d like to change the value of a custom project parameter so I need to use Element.GetChangeTypeParameter()
I have done this for Mark property as follow and it works fine:
ElementId paramId = new ElementId(BuiltInParameter.ALL_MODEL_MARK);
UpdaterRegistry.AddTrigger(Markupdater.GetUpdaterId(), categoryFilter, Element.GetChangeTypeParameter(paramId));
How can I apply a trigger to a custom project parameter, say “CEL Mark”?
Thanks,
Neda
Solved! Go to Solution.
Solved by saikat. Go to Solution.
Hello Neda
Would this help?
1) Access the category of the project parameter from ParameterBindings list (see ParameterBindings SDK to see how to access the Project Parameter and its category)
2) create filter for elements in the revit model which are belong to the same category
3) with one such element from filter, access the parameter (which is project parameter) and get its id
4) use this parameter id into the DMU code.
cheers
Hi Saikat,
you wrote:
"3) with one such element from filter, access the parameter(...)"
We need an Element to get the Parameter object.
I think that the Updater registration process usually takes place in the OnStartup method of an add-in.
In this state, there may be the case that no document is opened.
Thus, no element can be accessed.
Also, you need an element of the correct category.
Even if there is an opened document, it may be that there is no such element in it.
I would switch from GetChangeTypeParameter to GetChangeTypeAny (or GetChangeTypeGeometry if the parameter refers to geometry (length, height etc.)).
In your Updater class, you could check if the changed elements *have* your parameter.
If so, you can handle those elements in the way you want.
Cheers,
Revitalizer
Hi Saikat,
Thank you for your help. As you said,
3) with one such element from filter, access the parameter (which is project parameter) and get its id
my issue is how can I get id of my project parameter "CEL Mark". Because if it's a usual parameter I can get the id from BuiltInParameter and then use it in Element.GetChangeTypeParameter(ParameterId) in modify updater. For example, here I set a trigger for Mark parameter.
ElementId paramId = new ElementId(BuiltInParameter.ALL_MODEL_MARK);
UpdaterRegistry.AddTrigger(Markupdater.GetUpdaterId(), categoryFilter, Element.GetChangeTypeParameter(paramId));
Cheers,
Neda
Hi
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.
<code_begin>
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"));
}
}
<code_end>
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.
regards