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: 

Project Parameters not being created when a second document is opened

5 REPLIES 5
Reply
Message 1 of 6
sensiblehira
178 Views, 5 Replies

Project Parameters not being created when a second document is opened

//Create project parameters
public static Guid CreateProjectParameter(Document doc, string parameterName,
    string groupName, ForgeTypeId parameterType, ForgeTypeId parameterGroup, bool instance,
    System.Collections.Generic.IEnumerable<Category> categoryList)
{
    // buffer the current shared parameter file name and apply a new empty parameter file instead
    string sharedParameterFile = doc.Application.SharedParametersFilename;
    string tempSharedParameterFile = System.IO.Path.GetTempFileName() + ".txt";
    using (System.IO.File.Create(tempSharedParameterFile)) { }
    doc.Application.SharedParametersFilename = tempSharedParameterFile;

    //check if the parameter exists
    bool parameterExists;
    Autodesk.Revit.DB.Binding existing_binding;
    Definition existing_definition;

    (parameterExists, existing_binding, existing_definition) = 
        CheckProjectParameter(doc, parameterName);

    // Get the BindingMap of the current document
    BindingMap bindingMap = doc.ParameterBindings;

    // Apply selected parameter categories
    CategorySet categories = new CategorySet();
    if (categoryList == null) //if true parameter is applied to all the categories in the document
    {
        foreach (Category c in doc.Settings.Categories)
        {
            if (parameterExists) 
            {
                if (CheckParameterExistsForCategory(doc, existing_definition, existing_binding, c))
                {
                    continue;//if the parameter exists for the category no changes are needed
                }
            }
            if (c.AllowsBoundParameters)
            {
                categories.Insert(c);
            }
        }
    }
    else
    {
        foreach (Category c in categoryList)
        {
            if (parameterExists)
            {
                if (CheckParameterExistsForCategory(doc, existing_definition, existing_binding, c))
                {
                    continue;
                }
            }
            if (c.AllowsBoundParameters)
            {
                categories.Insert(c);
            }
        }
    }
    if (categories.IsEmpty)
    {
        //if (existing_definition is ExternalDefinition existingExternalDefinition) return existingExternalDefinition.GUID;
        /*FilteredElementCollector collector = new FilteredElementCollector(doc).OfClass(typeof(ParameterElement));
        foreach (SharedParameterElement para in collector)
        {
            if (para.Id == (InternalDefinition)existing_definition.Id) return para.GuidValue;
        }*/
        InternalDefinition existingInternalDefinition = (InternalDefinition)existing_definition;
        SharedParameterElement para = doc.GetElement(existingInternalDefinition.Id) as SharedParameterElement;
        //delete temp shared parameter file
        doc.Application.SharedParametersFilename = sharedParameterFile;
        System.IO.File.Delete(tempSharedParameterFile);
        return para.GuidValue;
    }
    if (!categories.IsEmpty && parameterExists)
    {
        //update category list
        if (existing_binding is InstanceBinding instanceBinding)
        {
            foreach (Category c in instanceBinding.Categories)
            {
                categories.Insert(c);
            }
        }
        if (existing_binding is TypeBinding TypeBinding)
        {
            foreach (Category c in TypeBinding.Categories)
            {
                categories.Insert(c);
            }
        }
        using (Transaction trans = new Transaction(doc, "Update Parameter Categories"))
        {
            trans.Start();
            Autodesk.Revit.DB.Binding newBinding = (instance) ?
            (Autodesk.Revit.DB.Binding)doc.Application.Create.NewInstanceBinding(categories) :
            (Autodesk.Revit.DB.Binding)doc.Application.Create.NewTypeBinding(categories);
            bindingMap.ReInsert(existing_definition, newBinding, parameterGroup);
            trans.Commit();
        }
        if (existing_definition is ExternalDefinition newDefinition)
        {
            //delete temp shared parameter file
            doc.Application.SharedParametersFilename = sharedParameterFile;
            System.IO.File.Delete(tempSharedParameterFile);
            return newDefinition.GUID;
        }
    }

    #region create new parameter

    // Get the shared parameter file object
    DefinitionFile defFile = doc.Application.OpenSharedParameterFile();
    // Create a new group for the shared parameter (if it doesn't exist)
    DefinitionGroup defGroup = defFile.Groups.get_Item(groupName) ?? defFile.Groups.Create(groupName);
    // Create the shared parameter definition (if it doesn't exist)
    ExternalDefinition definition = defGroup.Definitions.get_Item(parameterName) as ExternalDefinition;
    if (definition == null)
    {
        ExternalDefinitionCreationOptions options = new ExternalDefinitionCreationOptions(parameterName, parameterType)
        {
            Visible = true
        };
        definition = defGroup.Definitions.Create(options) as ExternalDefinition;
    }

    //create an instance or type binding
    Autodesk.Revit.DB.Binding binding = (instance) ?
        (Autodesk.Revit.DB.Binding)doc.Application.Create.NewInstanceBinding(categories) :
        (Autodesk.Revit.DB.Binding)doc.Application.Create.NewTypeBinding(categories);

    // Start a transaction to add the parameter
    using (Transaction tx = new Transaction(doc, "Add Project Parameter"))
    {
        tx.Start();

        // Bind the parameter to the document
        bool added = bindingMap.Insert(definition, binding, parameterGroup);
        //apply old shared parameter file
        doc.Application.SharedParametersFilename = sharedParameterFile;
        

        if (!added)
        {
            Autodesk.Revit.UI.TaskDialog.Show("Error", "Parameter binding failed.");
            //delete temp shared parameter file
            System.IO.File.Delete(tempSharedParameterFile);
            tx.RollBack();
            return definition.GUID;
        }

        tx.Commit();
    }
    //delete temp shared parameter file
    System.IO.File.Delete(tempSharedParameterFile);
    //TaskDialog.Show("Success", "Project parameter created and bound successfully.");
    #endregion
    return definition.GUID;
}

//If a parameter exists in the project check if it is assigned to the target category
public static bool CheckParameterExistsForCategory(Document doc, Definition definition, Autodesk.Revit.DB.Binding binding, Category targetCategory)
{
    bool output_bool;
    if (binding is InstanceBinding instanceBinding)
    {
        // Check if the target category is included in the binding
        CategorySet categories = instanceBinding.Categories;
        if (categories.Cast<Category>().Any(c => c.Id == targetCategory.Id))
        {
            output_bool = true;
        }
        else
        {
            output_bool = false;
        }
    }
    else
    {
        TypeBinding typeBinding = binding as TypeBinding;
        // Check if the target category is included in the binding
        CategorySet categories = typeBinding.Categories;
        if (categories.Cast<Category>().Any(c => c.Id == targetCategory.Id))
        {
            output_bool = true;
        }
        else
        {
            output_bool = false;
        }
    }
    return output_bool;
}

//Check if a paramater with the given name already exists in the project
public static (bool, Autodesk.Revit.DB.Binding, Definition) CheckProjectParameter(Document doc, string parameterName)
{
    // Access the parameter bindings in the document
    BindingMap bindingMap = doc.ParameterBindings;
    // Iterate through the parameter bindings
    for (DefinitionBindingMapIterator iterator = bindingMap.ForwardIterator(); iterator.MoveNext();)
    {
        Definition definition = iterator.Key;
        Autodesk.Revit.DB.Binding binding = iterator.Current as Autodesk.Revit.DB.Binding;

        // Check if the parameter name matches
        if (definition.Name == parameterName)
        {
            return (true, binding, definition);
        }
    }
    return (false, null, null);
}

I am using this method (CreateProjectParameter) to create project parameters. I am calling this function from OnDocumentOpened Event. The code runs fine(means the parameters are being created) when the first document is opened. But when I close this first Document and open a second one the parameters are not being created. I am having trouble finding the problem.

Tags (1)
Labels (1)
5 REPLIES 5
Message 2 of 6
sensiblehira
in reply to: sensiblehira

I have prepared a test file for the checking of the code, it is weird that when I open Revit and I open my test file it runs perfectly. When I close this file and open it again it doesn't work. Same is the case with any other file.

Message 3 of 6
ctm_mka
in reply to: sensiblehira

Have you verified that teh "sharedParameterFile" variable is valid all the way through the code on teh second run? my guess its it getting reset somewhere, but sounds like its not throwing an error? and have you tested with a different file on the second run?

Message 4 of 6
sensiblehira
in reply to: ctm_mka

tested with a second file, the error persists

Message 5 of 6
sensiblehira
in reply to: sensiblehira

I also think the error is because of the shared parameter file. Let me debug this further and return with results if any.

Message 6 of 6
scgq425
in reply to: sensiblehira

@sensiblehira :

 

in you code , you has use if statment to get the bool , and then use this code to change shareFile to old  file , maybe the error is : first run is create success but not run this code , and the line 154 or 146 deletd tmp file , so the second cant get a cuurrent openshareFile , you can debug this and check the second if set the current value.

 doc.Application.SharedParametersFilename = sharedParameterFile;

 

LanHui Xu
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature

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

Post to forums  

Autodesk Design & Make Report