Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IsChangeTriggered not responding as anticipated

8 REPLIES 8
SOLVED
Reply
Message 1 of 9
blro.
913 Views, 8 Replies

IsChangeTriggered not responding as anticipated

blro.
Enthusiast
Enthusiast

I've been pulling my hair out trying to query GetChangeTypeModified to react based on a series of concatenated parameter values.

 

So far, whenever I use the IsChangeTriggered method it returns false. Every time. On all of my parameters.

 

I think the way I'm referencing the Elements and their Parameters is correct because when I use both GetChangeType ElementAdded and GetChangeTypeElementModified, a) the calculations done correctly, setting the needed parameter and b) somethings get triggered (I just don't know what exactly).

 

Basically what I need to do here is: 

  1. Query my Shared Parameter for a change. Update the related Elevation Height Parameter respectively OR
  2. Query my Elevation Height Parameter for a change and update the related Shared Parameter OR
  3. Query the associated Level of the Element for a change and update the Shared Parameter OR
  4. If an element is added look at all three of these things and calculate the Shared Parameter 

 

ChangeType.ConcatenateChangeTypes(
                                Element.GetChangeTypeParameter(absHeight.Id), 
                                ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.INSTANCE_ELEVATION_PARAM)),
                                ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.FAMILY_LEVEL_PARAM)),
                                Element.GetChangeTypeElementAddition()))));

 

 

 

if (data.GetModifiedElementIds().Count() > 0)
                {
                    foreach (ElementId id in data.GetModifiedElementIds())
                    {
                    String whatChanged = data.GetModifiedElementIds().ToString();
                        Element e = doc.GetElement(id);
                        Parameter aEle = e.get_Parameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM);
                        Parameter aAbsLevel = e.get_Parameter(absHeightId);
                        Parameter aLevelP = e.get_Parameter(BuiltInParameter.FAMILY_LEVEL_PARAM);

                        //why aren't the parameters getting recognized as being changed?!
                        if (data.IsChangeTriggered(id, Element.GetChangeTypeParameter(aEle)))
                        {
                            TaskDialog.Show("The Elevation changed","The Elevation changed");

                        }
                        else if (data.IsChangeTriggered(id, Element.GetChangeTypeParameter(aLevelP)))
                        {
                            TaskDialog.Show("The Level changed", "The Level changed");
                        }
                        else if (data.IsChangeTriggered(id, Element.GetChangeTypeParameter(aAbsLevel)))
                    {
                            TaskDialog.Show("The Absolute Height changed","The Absolute Height changed");
                        }
                        else
                        {
                            TaskDialog.Show("Nothing was changed","Nothing was changed");
                        }

 

 

Essentially what I'm getting every time is a dialogue with the given title "Nothing was changed" if I modify any of these 3 parameters.

 

I'm wondering if what I'm experiencing is similar to here or here. (Which I can't tell if either were resolved.)

But being relatively inexperienced with the API, C#, and a rookie at programming generally, also don't know if my code or approach is just plain incorrect or missing something (iterating the wrong thing for example).

 

Big thanks in advanced to those that can help. Whether it be with my code, my insecurities, or my sanity.

 

0 Likes

IsChangeTriggered not responding as anticipated

I've been pulling my hair out trying to query GetChangeTypeModified to react based on a series of concatenated parameter values.

 

So far, whenever I use the IsChangeTriggered method it returns false. Every time. On all of my parameters.

 

I think the way I'm referencing the Elements and their Parameters is correct because when I use both GetChangeType ElementAdded and GetChangeTypeElementModified, a) the calculations done correctly, setting the needed parameter and b) somethings get triggered (I just don't know what exactly).

 

Basically what I need to do here is: 

  1. Query my Shared Parameter for a change. Update the related Elevation Height Parameter respectively OR
  2. Query my Elevation Height Parameter for a change and update the related Shared Parameter OR
  3. Query the associated Level of the Element for a change and update the Shared Parameter OR
  4. If an element is added look at all three of these things and calculate the Shared Parameter 

 

ChangeType.ConcatenateChangeTypes(
                                Element.GetChangeTypeParameter(absHeight.Id), 
                                ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.INSTANCE_ELEVATION_PARAM)),
                                ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.FAMILY_LEVEL_PARAM)),
                                Element.GetChangeTypeElementAddition()))));

 

 

 

if (data.GetModifiedElementIds().Count() > 0)
                {
                    foreach (ElementId id in data.GetModifiedElementIds())
                    {
                    String whatChanged = data.GetModifiedElementIds().ToString();
                        Element e = doc.GetElement(id);
                        Parameter aEle = e.get_Parameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM);
                        Parameter aAbsLevel = e.get_Parameter(absHeightId);
                        Parameter aLevelP = e.get_Parameter(BuiltInParameter.FAMILY_LEVEL_PARAM);

                        //why aren't the parameters getting recognized as being changed?!
                        if (data.IsChangeTriggered(id, Element.GetChangeTypeParameter(aEle)))
                        {
                            TaskDialog.Show("The Elevation changed","The Elevation changed");

                        }
                        else if (data.IsChangeTriggered(id, Element.GetChangeTypeParameter(aLevelP)))
                        {
                            TaskDialog.Show("The Level changed", "The Level changed");
                        }
                        else if (data.IsChangeTriggered(id, Element.GetChangeTypeParameter(aAbsLevel)))
                    {
                            TaskDialog.Show("The Absolute Height changed","The Absolute Height changed");
                        }
                        else
                        {
                            TaskDialog.Show("Nothing was changed","Nothing was changed");
                        }

 

 

Essentially what I'm getting every time is a dialogue with the given title "Nothing was changed" if I modify any of these 3 parameters.

 

I'm wondering if what I'm experiencing is similar to here or here. (Which I can't tell if either were resolved.)

But being relatively inexperienced with the API, C#, and a rookie at programming generally, also don't know if my code or approach is just plain incorrect or missing something (iterating the wrong thing for example).

 

Big thanks in advanced to those that can help. Whether it be with my code, my insecurities, or my sanity.

 

8 REPLIES 8
Message 2 of 9
Sean_Page
in reply to: blro.

Sean_Page
Collaborator
Collaborator

What does your code look like when you register the updated initially? More specifically, which change type did u indicate there?

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
0 Likes

What does your code look like when you register the updated initially? More specifically, which change type did u indicate there?

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
Message 3 of 9
blro.
in reply to: Sean_Page

blro.
Enthusiast
Enthusiast

@Sean_Page wrote:

What does your code look like when you register the updated initially? More specifically, which change type did u indicate there?


ChangeType.ConcatenateChangeTypes(
                                Element.GetChangeTypeParameter(absHeight.Id), 
                                ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.INSTANCE_ELEVATION_PARAM)),
                                ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.FAMILY_LEVEL_PARAM)),
                                Element.GetChangeTypeElementAddition()))));

 

Does that help or do you want to see the whole Execute and Filtering code?

 

public Result Execute(ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiApp = commandData.Application;
            Document doc = uiApp.ActiveUIDocument.Document;

            //get "ElementZuordnung" parameter (Guid from shared parameters file)
            Guid elemZuordId = new Guid(redacted);
            Guid absHeightId = new Guid(redacted);

            //Rule out older or external projects that don't contain identifying parameter for trigger
            //Collect generic model types
            FilteredElementCollector genModelCollector = new FilteredElementCollector(doc).WhereElementIsElementType().OfCategory(BuiltInCategory.OST_GenericModel);

            if (null != genModelCollector)
            {
                //Check to see if there are any generic model elements in current model
                Element eCheck = genModelCollector.ToElements().First() as Element;

                if (null != eCheck)
                {
                    if (null != eCheck.get_Parameter(elemZuordId))
                    {
                        AussparungUpdater updater = new AussparungUpdater(uiApp.ActiveAddInId);
                        UpdaterRegistry.RegisterUpdater(updater);

                        //Filter for Generic Model
                        ElementCategoryFilter genModFilter = new ElementCategoryFilter(BuiltInCategory.OST_GenericModel);
                        ElementClassFilter familyInstanceFilter = new ElementClassFilter(typeof(FamilyInstance));
                        LogicalAndFilter genModInstFilter = new LogicalAndFilter(familyInstanceFilter, genModFilter);
                        
                        //parameter filter for only allowing gen models with the correct parameter to be triggered
                        //still not sure why I need to look up a shared parameter by its GUID, get the parameter
                        //as an element, then go back and get it's Id again, but here we are. Note: it's because only builtin params
                        //work with pvp and as well the trigger getchangetypeparameter below (AFAIK)
                        SharedParameterElement elemZuord = SharedParameterElement.Lookup(doc, elemZuordId);
                        SharedParameterElement absHeight = SharedParameterElement.Lookup(doc, absHeightId);


                        ParameterValueProvider pvp = new ParameterValueProvider(elemZuord.Id);

                        FilterStringEquals paramEq = new FilterStringEquals();
                        string s = "Aussparung";
                        FilterRule rule = new FilterStringRule(pvp, paramEq, s, false);

                        ElementParameterFilter zuordFilter = new ElementParameterFilter(rule);

                        LogicalAndFilter aussparFilter = new LogicalAndFilter(genModInstFilter, zuordFilter);

                        //Triggers on creation of or changes to instances of Generic Models and the parameter 
                        UpdaterRegistry.AddTrigger(
                            updater.GetUpdaterId(), 
                            aussparFilter, 
                            ChangeType.ConcatenateChangeTypes(
                                Element.GetChangeTypeParameter(absHeight.Id), 
                                ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.INSTANCE_ELEVATION_PARAM)),
                                ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.FAMILY_LEVEL_PARAM)),
                                Element.GetChangeTypeElementAddition()))));

                    }
                } 
            }


            return Result.Succeeded;
        }

 

0 Likes


@Sean_Page wrote:

What does your code look like when you register the updated initially? More specifically, which change type did u indicate there?


ChangeType.ConcatenateChangeTypes(
                                Element.GetChangeTypeParameter(absHeight.Id), 
                                ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.INSTANCE_ELEVATION_PARAM)),
                                ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.FAMILY_LEVEL_PARAM)),
                                Element.GetChangeTypeElementAddition()))));

 

Does that help or do you want to see the whole Execute and Filtering code?

 

public Result Execute(ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiApp = commandData.Application;
            Document doc = uiApp.ActiveUIDocument.Document;

            //get "ElementZuordnung" parameter (Guid from shared parameters file)
            Guid elemZuordId = new Guid(redacted);
            Guid absHeightId = new Guid(redacted);

            //Rule out older or external projects that don't contain identifying parameter for trigger
            //Collect generic model types
            FilteredElementCollector genModelCollector = new FilteredElementCollector(doc).WhereElementIsElementType().OfCategory(BuiltInCategory.OST_GenericModel);

            if (null != genModelCollector)
            {
                //Check to see if there are any generic model elements in current model
                Element eCheck = genModelCollector.ToElements().First() as Element;

                if (null != eCheck)
                {
                    if (null != eCheck.get_Parameter(elemZuordId))
                    {
                        AussparungUpdater updater = new AussparungUpdater(uiApp.ActiveAddInId);
                        UpdaterRegistry.RegisterUpdater(updater);

                        //Filter for Generic Model
                        ElementCategoryFilter genModFilter = new ElementCategoryFilter(BuiltInCategory.OST_GenericModel);
                        ElementClassFilter familyInstanceFilter = new ElementClassFilter(typeof(FamilyInstance));
                        LogicalAndFilter genModInstFilter = new LogicalAndFilter(familyInstanceFilter, genModFilter);
                        
                        //parameter filter for only allowing gen models with the correct parameter to be triggered
                        //still not sure why I need to look up a shared parameter by its GUID, get the parameter
                        //as an element, then go back and get it's Id again, but here we are. Note: it's because only builtin params
                        //work with pvp and as well the trigger getchangetypeparameter below (AFAIK)
                        SharedParameterElement elemZuord = SharedParameterElement.Lookup(doc, elemZuordId);
                        SharedParameterElement absHeight = SharedParameterElement.Lookup(doc, absHeightId);


                        ParameterValueProvider pvp = new ParameterValueProvider(elemZuord.Id);

                        FilterStringEquals paramEq = new FilterStringEquals();
                        string s = "Aussparung";
                        FilterRule rule = new FilterStringRule(pvp, paramEq, s, false);

                        ElementParameterFilter zuordFilter = new ElementParameterFilter(rule);

                        LogicalAndFilter aussparFilter = new LogicalAndFilter(genModInstFilter, zuordFilter);

                        //Triggers on creation of or changes to instances of Generic Models and the parameter 
                        UpdaterRegistry.AddTrigger(
                            updater.GetUpdaterId(), 
                            aussparFilter, 
                            ChangeType.ConcatenateChangeTypes(
                                Element.GetChangeTypeParameter(absHeight.Id), 
                                ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.INSTANCE_ELEVATION_PARAM)),
                                ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.FAMILY_LEVEL_PARAM)),
                                Element.GetChangeTypeElementAddition()))));

                    }
                } 
            }


            return Result.Succeeded;
        }

 

Message 4 of 9
Sean_Page
in reply to: blro.

Sean_Page
Collaborator
Collaborator

According to the API reference the ChangeTypes do not work with ClassFilters.

 

https://www.revitapidocs.com/2018.1/776a59e3-3214-8250-64ca-41ec913257d5.htm

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
0 Likes

According to the API reference the ChangeTypes do not work with ClassFilters.

 

https://www.revitapidocs.com/2018.1/776a59e3-3214-8250-64ca-41ec913257d5.htm

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
Message 5 of 9
blro.
in reply to: Sean_Page

blro.
Enthusiast
Enthusiast

@Sean_Page wrote:

According to the API reference the ChangeTypes do not work with ClassFilters.

 

https://www.revitapidocs.com/2018.1/776a59e3-3214-8250-64ca-41ec913257d5.htm


 

Did not even see that. I guess I'll give it a go. 

 

My question would be then: why is the trigger still working? The GetModifiedElementIds and GetAddedElementIds methods still return a value when the right changes are made and the right elements are added, it's just the IsChangeTriggered that doesn't respond. Am I getting things mixed up here?

 

Also: if this is true, it would be far from ideal, as I'd be triggering my code every time I add or edit the level/elevation of any generic model 😞 I wanted to keep this program as lean as possible

0 Likes


@Sean_Page wrote:

According to the API reference the ChangeTypes do not work with ClassFilters.

 

https://www.revitapidocs.com/2018.1/776a59e3-3214-8250-64ca-41ec913257d5.htm


 

Did not even see that. I guess I'll give it a go. 

 

My question would be then: why is the trigger still working? The GetModifiedElementIds and GetAddedElementIds methods still return a value when the right changes are made and the right elements are added, it's just the IsChangeTriggered that doesn't respond. Am I getting things mixed up here?

 

Also: if this is true, it would be far from ideal, as I'd be triggering my code every time I add or edit the level/elevation of any generic model 😞 I wanted to keep this program as lean as possible

Message 6 of 9
Sean_Page
in reply to: blro.

Sean_Page
Collaborator
Collaborator

From what I read and have seen, I don't believe this keeps the Updater from firing, it just doesn't report the specific change type similar to ChangeTypeAny. 

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
0 Likes

From what I read and have seen, I don't believe this keeps the Updater from firing, it just doesn't report the specific change type similar to ChangeTypeAny. 

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
Message 7 of 9
blro.
in reply to: Sean_Page

blro.
Enthusiast
Enthusiast
Accepted solution

The problem was that I was concatenating the changes (and I assume not querying  the whole concatenation? although I've not tested this.)

 

By registering the trigger types separately, it's now working as expected:

 

UpdaterRegistry.AddTrigger(
            updater.GetUpdaterId(),
            doc,
            genModFilter,
            Element.GetChangeTypeElementAddition());

            UpdaterRegistry.AddTrigger(
            updater.GetUpdaterId(),
            doc,
            genModFilter,
            Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.INSTANCE_ELEVATION_PARAM)));

            UpdaterRegistry.AddTrigger(
            updater.GetUpdaterId(),
            doc,
            genModFilter,
            Element.GetChangeTypeParameter(absHeight.Id));

Thank you for taking the time and all your help @Sean_Page !

The problem was that I was concatenating the changes (and I assume not querying  the whole concatenation? although I've not tested this.)

 

By registering the trigger types separately, it's now working as expected:

 

UpdaterRegistry.AddTrigger(
            updater.GetUpdaterId(),
            doc,
            genModFilter,
            Element.GetChangeTypeElementAddition());

            UpdaterRegistry.AddTrigger(
            updater.GetUpdaterId(),
            doc,
            genModFilter,
            Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.INSTANCE_ELEVATION_PARAM)));

            UpdaterRegistry.AddTrigger(
            updater.GetUpdaterId(),
            doc,
            genModFilter,
            Element.GetChangeTypeParameter(absHeight.Id));

Thank you for taking the time and all your help @Sean_Page !

Message 8 of 9
Sean_Page
in reply to: blro.

Sean_Page
Collaborator
Collaborator

Glad to hear you got it working!

May I ask if you were able to keep the Class filter? Looking at your code above, it appears not, but was interested if that worked.

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
0 Likes

Glad to hear you got it working!

May I ask if you were able to keep the Class filter? Looking at your code above, it appears not, but was interested if that worked.

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
Message 9 of 9
blro.
in reply to: Sean_Page

blro.
Enthusiast
Enthusiast

I hadn't put the class filter back in until just now, but it seems to be working with it 🙂

0 Likes

I hadn't put the class filter back in until just now, but it seems to be working with it 🙂

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report