Many times we’d like to redefine, rebind, or replace some exisitng project parameters. In this post, we will talk about what can be done, how to achieve it with the Revit API, and what can not be done.
Revit Parameter Organizer can organize various Revit parameters such as Shared Parameters, Family Parameters, Project Parameters and Built-in Parameter in many good ways.
Can we redefine an project parameter which is defined from a shared parameter?
Yes, supposing the shared parameter definition is still there in the DefinitionGroup and in turn in the DefinitionFile:
public static void RawReplaceProjectParameterWithExistingSharedParameter(RvtApplication app, string name, CategorySet cats, BuiltInParameterGroup group, bool inst)
{
DefinitionFile defFile = app.OpenSharedParameterFile();
if (defFile == null) throw new Exception("No SharedParameter File!");
var v = (from DefinitionGroup dg in defFile.Groups
from ExternalDefinition d in dg.Definitions
where d.Name == name
select d);
if (v == null || v.Count() < 1) throw new Exception("Invalid Name Input!");
ExternalDefinition def = v.First();
Autodesk.Revit.DB.Binding binding = app.Create.NewTypeBinding(cats);
if (inst) binding = app.Create.NewInstanceBinding(cats);
BindingMap map = (new UIApplication(app)).ActiveUIDocument.Document.ParameterBindings;
map.ReInsert(def, binding, group);
}
Can we update the categories only of an existing project parameter regardless of where it is defined from (project or shared parameter)?
No. The following code tries its best but without any luck:
public static void RawRecategorizeProjectParameter(RvtDocument doc, string name, CategorySet cats)
{
BindingMap map = doc.ParameterBindings;
Definition def = map.GetDefiniton(name);
Autodesk.Revit.DB.Binding binding = map.GetBinding(name);
if (def == null || binding == null) return;
CategorySet oriCats = null;
if ((binding as InstanceBinding) != null)
oriCats = (binding as InstanceBinding).Categories;
else
oriCats = (binding as TypeBinding).Categories;
oriCats.Clear();
foreach (Category cat in cats)
oriCats.Insert(cat);
map.ReInsert(def, binding);
}
Can we change the binding only of an existing project parameter?
No. The following code does not seem to have anything wrong but it just can not make the job done:
public static void RawRebindProjectParameter(RvtDocument doc, string name, CategorySet cats, BuiltInParameterGroup group, bool inst)
{
BindingMap map = doc.ParameterBindings;
Definition def = map.GetDefiniton(name);
Autodesk.Revit.DB.Binding binding = doc.Application.Create.NewTypeBinding(cats);
if (inst) binding = doc.Application.Create.NewInstanceBinding(cats);
map.ReInsert(def, binding, group);
}
If the original shared parameter definition file is lost, can we redefining a shared project parameter?
No. The following code, which uses the technique of temporary shared parameter definition and external file that we introduced before, can not replace the existing shared project parameter:
public static void RawReplaceProjectParameterWithTempSharedParameter(RvtApplication app, string name, ParameterType type, bool visible, CategorySet cats, BuiltInParameterGroup group, bool inst)
{
string oriFile = app.SharedParametersFilename;
string tempFile = Path.GetTempFileName() + ".txt";
using (File.Create(tempFile)) { }
app.SharedParametersFilename = tempFile;
ExternalDefinition def = app.OpenSharedParameterFile().Groups.Create("TemporaryDefintionGroup").Definitions.Create(name, type, visible) as ExternalDefinition;
app.SharedParametersFilename = oriFile;
File.Delete(tempFile);
Autodesk.Revit.DB.Binding binding = app.Create.NewTypeBinding(cats);
if (inst) binding = app.Create.NewInstanceBinding(cats);
BindingMap map = (new UIApplication(app)).ActiveUIDocument.Document.ParameterBindings;
map.ReInsert(def, binding, group);
}
The following code can test these methods:
…
//Please create the project parameter 'PrjParameter' first.
RawRecategorizeProjectParameter(CachedDoc, "PrjParameter", cats1);
//Please create the project parameter "Volume42' first.
RawRebindProjectParameter(CachedDoc, "Volume42", cats1, BuiltInParameterGroup.PG_STRUCTURAL, false);
//RawCreateProjectParameterFromExistingSharedParameter(CachedApp, "ExistingParameter1", cats1, BuiltInParameterGroup.PG_DATA, false);
RawReplaceProjectParameterWithExistingSharedParameter(CachedApp, "ExistingParameter1", cats1, BuiltInParameterGroup.PG_IFC, true);
//RawCreateProjectParameter(CachedApp, "TemporarySharedParameter", ParameterType.Text, true, cats1, BuiltInParameterGroup.PG_DATA, true);
RawReplaceProjectParameterWithTempSharedParameter(CachedApp, "TemporarySharedParameter", ParameterType.Text, true, cats1, BuiltInParameterGroup.PG_DISPLAY, false);
…
So except for the first scenario, it seems the only way is to erase the existing project parameter regardless of its origin and create a new one from a shared parameter. This time, the shared parameter can be from a real in use external definition file or a temporary one.
ProjectParameter Reshaper of Revit Addin Coder will take care of these for us.
Recent Comments