VariesAcrossGroups lost when ReInsert_ing doc.ParameterBindings?

VariesAcrossGroups lost when ReInsert_ing doc.ParameterBindings?

Anonymous
Not applicable
840 Views
5 Replies
Message 1 of 6

VariesAcrossGroups lost when ReInsert_ing doc.ParameterBindings?

Anonymous
Not applicable

Our plugin maintains some instance parameter values across many elements, including those in groups.

Occasionally the end users will introduce data that activates an unused Category,

so we have to update the document parameter bindings, to include those categories.

 

However, when we call

doc.ParameterBindings.ReInsert()

our existing parameter values inside groups are lost, because our VariesAcrossGroups flag is toggled back to false?

How did Revit intend this to work - are we supposed to use this in a different way, to not trigger this problem?

 

ReInsert() expects a base Definition argument, and would usualy get an ExternalDefinition supplied.

To learn, I instead tried to scan through the definition-keys of existing bindings and match those.

This way, I got the document's InternalDefinition, and tried calling Reinsert with that instead

(my hope was, that since its existing InternalDefinition DID include VariesAcrossGroups=true, this would help.)

Alas, Reinsert  doesn't seem to care.

 

The problem, as you might guess, is that after VariesAcrossGroups=False, a lot of my instance parameters have collapsed into each other, so they all hold identical values. Given that they are IDs, this is less than ideal.

 

My current (intended) solution is to instead grab a backup of all existing parameter values BEFORE I update the bindings, then after the binding-update and variesAcrossGroups back to true,

then inspect all values and re-assign all parameter-values that have been broken.

But as you may surmise, this is less than ideal - it will be horribly slow for the users to use our plugin,

and frankly it seems like something the revitAPI should take care of, not the plugin developer.

Are we using this the wrong way?

One approach I have considered, is to bind every possibly category I can think of, up front and once only.

  But I'm not sure that is possible. Categories in themselves are also difficult to work with, as you can only create them indirectly, by using your Project-Document as a factory (i.e. you cannot create a category yourself, you can only indirectly ask the Document to - maybe! - create a category for you, that you request). Because of this, I don't think you can bind for all categories up front - some categories only become available  in the document, AFTER you have included a given family/type in your project.

 

To sum it up:

First, I

doc.ParameterBindings.ReInsert() my binding, with the updated categories.

Then, I call InternalDefinition.SetAllowVaryBetweenGroups()

(after having determined IDEF.VariesAcrossGroups has reverted back to false.)

 

I am interested to hear the best way to do this, without destroying the client's existing data.

 

Thank you very much in advance.

841 Views
5 Replies
Replies (5)
Message 2 of 6

ChrisHildebranAtWork
Contributor
Contributor

JG, we are currently experiencing the exact behavior and am wondering if youd found a solution.

Chris Hildebran
VDC Software Development
IBEW 48 Wireman
ISA CCST 1
JH Kelly, LLC
0 Likes
Message 3 of 6

Anonymous
Not applicable
No, unfortunately. I still handle it in the manual cumbersome way I described, ie I back up the critical data before updating, then write it back in places where it has changed. However, given it only affects data in groups, it is possible to narrow down the affected data somewhat (e.g. group members will have data in Element.GroupId.)
Message 4 of 6

RPTHOMAS108
Mentor
Mentor

Have you tried iterating the BindingMap and changing the category set for the matching definition i.e. change ElementBinding.Categories in place? I'm not sure this is possible but seems odd to ReInsert when the definition hasn't changed only the category set has.

 

There are warnings about set_Item on BindingMap however. Not sure if that extends to the members of the item or if the item of the iterator is detached from original so changes to it are pointless without reinserting.

 

Most categories exist without an element of such needing to, what was the issue binding to all? Document.Settings.Categories you can iterate it and check Categoeries.AllowsBoundParameters.

0 Likes
Message 5 of 6

ChrisHildebranAtWork
Contributor
Contributor
Thanks for the insight JG!
Chris Hildebran
VDC Software Development
IBEW 48 Wireman
ISA CCST 1
JH Kelly, LLC
0 Likes
Message 6 of 6

f_cucchi_FocchiSpa
Explorer
Explorer

Hi jg,  to avoid this problem you need to set SetAllowVaryBetweenGroups =false BEFORE calling ReInsert method and then bring back SetAllowVaryBetweenGroups = true if it's necessary. If you do this inside a transaction you don't lose data.

This happens always when exixts at least one GroupType into the model.

 

Here the code snippet:

using (Transaction t = new Transaction(doc, "Reinsert"))
{
    t.start();

    InternalDefinition intDef = def as InternalDefinition

    bool canVary = intDef.VariesAcrossGroups;
    intDef.SetAllowVaryBetweenGroups(doc, false);

    if (!doc.ParameterBindings.ReInsert(extDef, ib, pGroup))
    {
        doc.ParameterBindings.Remove(defFound);
        doc.ParameterBindings.Insert(extDef, ib, pGroup);
    }

    // If 'canVary' was true bring it back to true  
    if (canVary)
        intDef.SetAllowVaryBetweenGroups(doc, true);

    t.commit();
}

 

Let me know if it works for you.

Bye.

 

Federico Cucchi

0 Likes