Announcements
Due to scheduled maintenance, the Autodesk Community will be inaccessible from 10:00PM PDT on Oct 16th for approximately 1 hour. We appreciate your patience during this time.
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: 

Add category to existing parameter

3 REPLIES 3
SOLVED
Reply
Message 1 of 4
ottosson_mathias
432 Views, 3 Replies

Add category to existing parameter

How can I update an existing parameters category list? I'm trying to create a utility function that adds parameters with value to elements. And it can add parameters to elements just fine. The problem is when I want to add the same parameter to another type of element.

 

So let's say I run the function on a collection of MEP_spaces and another time for a collection of analytical_spaces, it will create two different parameters by the same name but with different categories specified.

 

I want to be able to check if there exists a parameter by the specified name and if so check if the element category has been set, and if not, set it!

 

Easiest thing in the world to do in the UI, but for some reason I can't figure out how to do it with the API. As you can see in the code below I remove the shared parameters file so I can't get it anymore, as I've seen people suggest to use it in other similar posts.

 

Here's how I use the method:

 

 

var spaces = new FilteredElementCollector(RevitAPI.doc).OfCategory(BuiltInCategory.OST_MEPSpaces).WhereElementIsNotElementType().ToElements();
var analytical_spaces = new FilteredElementCollector(RevitAPI.doc).OfCategory(BuiltInCategory.OST_AnalyticSpaces).WhereElementIsNotElementType().ToElements();

using (var transaction = new Transaction(RevitAPI.doc))
{
    transaction.Start("Set parameter values");
    SetParameterValue(spaces, "new value", "myParameterName", "groupName", SpecTypeId.String.Text, BuiltInParameterGroup.PG_IFC);
    SetParameterValue(analytical_spaces, "new value", "myParameterName", "groupName", SpecTypeId.String.Text, BuiltInParameterGroup.PG_IFC);
    transaction.Commit();
}

 

 

 And here's the method:

 

 

public static bool SetParameterValue(IEnumerable<Element> elements, string value, string parameterName, string parameterGroupName, ForgeTypeId parameterType, BuiltInParameterGroup bipGroup = BuiltInParameterGroup.INVALID)
{
    var targetCategories = new Dictionary<BuiltInCategory, Category>();

    foreach (var element in elements)
    {
        var elementBic = (BuiltInCategory)element.Category.Id.IntegerValue;
        var hasCategory = targetCategories.ContainsKey(elementBic);

        if (hasCategory == true)
        {
            continue;
        }

        var hasParameter = element.GetParameters(parameterName).Count > 0;

        if (hasParameter == false)
        {
            var elementCategory = element.Document.Settings.Categories.get_Item(elementBic);
            targetCategories[elementBic] = elementCategory;
        }
    }

    if (targetCategories.Count == 0)
    {
        // if all elements already have parameter, set values and return without adding parameters
        return UpdateValues(elements, value, parameterName);
    }

    var sharedParameterFilePath = $"C:/temp/{Guid.NewGuid()}.txt";
    var sharedParamsFile = GetSharedParamsFile(RevitAPI.app, sharedParameterFilePath);
    var sharedParamsGroup = sharedParamsFile.Groups.get_Item(parameterGroupName);

    if (sharedParamsGroup == null)
    {
        sharedParamsGroup = sharedParamsFile.Groups.Create(parameterGroupName);
    }

    foreach (var category in targetCategories.Values)
    {
        var groupParameterDefinition = sharedParamsGroup.Definitions.get_Item(parameterName);

        if (groupParameterDefinition == null)
        {
            groupParameterDefinition = sharedParamsGroup.Definitions.Create(new ExternalDefinitionCreationOptions(parameterName, parameterType)
            {
                Visible = category.AllowsBoundParameters,
                UserModifiable = false,
            });
        }

        var categorySet = RevitAPI.app.Create.NewCategorySet();
        categorySet.Insert(category);
        var binding = RevitAPI.app.Create.NewInstanceBinding(categorySet);

        RevitAPI.doc.ParameterBindings.Insert(groupParameterDefinition, binding, bipGroup);
    }

    File.Delete(sharedParameterFilePath);

    return UpdateValues(elements, value, parameterName);
}

private static bool UpdateValues(IEnumerable<Element> elements, string value, string parameterName)
{
    foreach (var element in elements)
    {
        var parameter = element.GetParameters(parameterName);

        if (parameter.Count > 0)
        {
            var succeeded = parameter[0].Set(value);

            if (succeeded == false)
            {
                return false;
            }
        }
    }

    return true;
}

private static DefinitionFile GetSharedParamsFile(Autodesk.Revit.ApplicationServices.Application app, string path)
{
    File.WriteAllText(path, string.Empty);

    app.SharedParametersFilename = path;
    var sharedParametersFile = app.OpenSharedParameterFile();

    return sharedParametersFile;
}

 

 

 

3 REPLIES 3
Message 2 of 4

Hi @ottosson_mathias,

 

See this post: DefinitionBindingMapIterator

 

The iterator key itself is the Definition (from this you can check the name of the project parameter)

The ElementBinding there's a property Categories which returns the categories attached to this project parameter. (see: ElementBinding.Categories Property)

This property is read/write so other categories can be added (set the whole CategorySet with additional categories)

 

- Michel

 

ps. "iterator.Current" = > ElementBinding (which can be cast to InstanceBinding or TypeBinding, type of instance bound)

 

Message 3 of 4

Update,

I have a addin that shows all the project parameter and their bound categories in a table format.

I'm updating this now to include columns with the shared status and GUID.

 

In the process I discovered that adding categories afterwards can only be done to shared parameters.

Use the Reinsert method (see: BindingMap.ReInsert Method ), this returns True if succesfull.

 

Hope this helps.

Message 4 of 4

Awesome! Thanks a lot

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

Post to forums  

Rail Community


Autodesk Design & Make Report