Revit API equivalent to "apply" button while editing parameters and types?

Revit API equivalent to "apply" button while editing parameters and types?

adam_konca
Enthusiast Enthusiast
941 Views
6 Replies
Message 1 of 7

Revit API equivalent to "apply" button while editing parameters and types?

adam_konca
Enthusiast
Enthusiast

Hello,

 

We have a family that needs its types and parameters edited all at once, then applied using the UI "apply" button. It works fine in the UI, we edit all the parameters, switch to a different type, edit some parameters, hit apply and it's all good.

 

However, while doing this through the API, it looks like Revit API hits "apply' after every single familyManager.Set(param, value) call. I've tried to move all parameter and type actions to a single transaction, but nothing changed.

 

Is there a way to stop Revit from automatically hitting "apply" after every single param edit and then call some function manually to case the "apply" action?

 

Thanks in advance,

Adam

0 Likes
942 Views
6 Replies
Replies (6)
Message 2 of 7

Kennan.Chen
Advocate
Advocate

You can use delegate to cache all the 'Set' operations and execute them one by one on applying.

 

Here's a simple demo.

public class AccumulatedFamilyParameterSetter
{
  public AccumulatedFamilyParameterSetter(Document document)
  {
    Actions = new List<Action>();
    Document = document;
    Manager = Document.FamilyManager;
  }

  private IList<Action> Actions { get; }
  private Document Document { get; }
  private FamilyManager Manager { get; }

  public void Set(FamilyParameter param, ElementId value)
  {
    Actions.Add(() => Manager.Set(param, value))
  }

  public void Set(FamilyParameter param, double value)
  {
    Actions.Add(() => Manager.Set(param, value))
  }

  public void Set(FamilyParameter param, int value)
  {
    Actions.Add(() => Manager.Set(param, value))
  }

  public void Set(FamilyParameter param, string value)
  {
    Actions.Add(() => Manager.Set(param, value))
  }

  public void Apply()
  {
    using(var transaction = new Transaction(Document,"Set Family Parameters"))
    {
      transaction.Start();
      Actions.ForEach(action => action());
      transaction.Commit()
    }
  }
}

 

0 Likes
Message 3 of 7

adam_konca
Enthusiast
Enthusiast

Thanks for the answer. I've already tried setting all the parameters in a single transaction. Is your "AccumulatedFamilyParameterSetter" any different from this?

 

using(var transaction = new Transaction(Document,"Set Family Parameters"))
    {
      transaction.Start();
      familyManager.Set(param1, value1);
      familyManager.Set(param2, value2);
      familyManager.Set(param3, value3);
      familyManager.CurrentType = "Some other type";
      familyManager.Set(param1, value4);
      familyManager.Set(param2, value5);
      transaction.Commit()
    }

 

 Because this is the way I do it now (simplified of course, but the point is, it's all in the same transaction), and it looks like "apply" is being hit after each familyManager.Set call (or at least something that simulates "apply", because I've also noticed that familyManager.Set sometimes throws errors that are only thrown in UI when I hit "apply" and not before).

0 Likes
Message 4 of 7

Kennan.Chen
Advocate
Advocate

Sounds interesting. Can you give some cases in which you don't want the 'Set' operation to be applied immediately?

0 Likes
Message 5 of 7

adam_konca
Enthusiast
Enthusiast

Sure.

 

1. Our client has a family (RFA) with multiple family types. Up until this point, they've edited everything manually (each parameter in all types), then hit the apply button. If they edit some parameters in one type, but not the other, they say the whole model breaks, because everything is connected.

 

2. Let's say you have 3 parameters: A, B and C. Parameters A and B are normal parameters, nothing fancy about them. Parameter C value is taken from lookup table (size_lookup formula) based on parameters A and B. Let's assume that lookup table has value for C based on 2 combinations of A and B:
A = 10 and B = 15 gives C = 100
A = 20 and B = 40 gives C = 177

Now, imagine we want to switch A from 10 to 20 and B from 15 to 40. If we hit apply between changing A and B, the error is thrown because lookup table does not have value for combination of A 20 and B 15.

0 Likes
Message 6 of 7

RPTHOMAS108
Mentor
Mentor

Sounds like a limitation with the API if parameters are not changed simultaneouslyy upon transaction commit then I suspect there is no other mechanism for that. To overcome the issue there are probably a number of far from ideal solutions specific to size lookups:

 

Option 1) Lookup formulas can have a default if not found value set. So this should be set to something neutral in the family.

Option 2) Can remove lookup formulas from parameters and cache their values in 1st transaction, set values of parameters in 2nd transaction, restore parameter formulas in final transaction. May be possible to group some of these stages into subtransactions.

Option 3) I left the most horrendous for last. Use FamilySizeTableManager to temporarily add the permutations of parameter values to be set in the named lookup table. 

0 Likes
Message 7 of 7

adam_konca
Enthusiast
Enthusiast

Yes, problem number 2 (lookup tables) can be solved with some workarounds as you said. To bo honest, I am more concerned about problem number 1, because in this case I have no idea how to approach it.

0 Likes