Revit project parameters are different from built-in parameters (BuiltInParameter), family parameters (FamilyParameter), and shared parameters. Project parameters may relate to shared parameters in some way as talked about previously.
Revit Parameter Organizer can organize various Revit parameters such as Shared Parameters, Family Parameters, Project Parameters and Built-in Parameter in many good ways.
As can be seen from the Project Parameters dialog in Revit, project parameters can be defined from both ‘project parameters’ themselves and shared parameters.
The former is not achievable programmatically due to the fact that InternalDefinition or native Parameter cannot be created with the Revit API. Though there is an InternalDefinitions.Create() method in the API and it looks like being supposed to fulfill the task but the point is that nowhere and no way to get an instance of InternalDefinitions.
The latter is doable programmatically through different ways, from existing shared parameters, from newly created shared parameters, or from temporary shared parameters in some temporary external definition files. In fact, in the post of Parameter of Revit API – 25: Attach Shared Parameter, we have already introduced the first approach, creating a project parameter from an existing shared parameter or attaching a shared parameter to some categories (indirectly to elements).
Revit Parameter Organizer can organize various Revit parameters such as Shared Parameters, Family Parameters, Project Parameters and Built-in Parameter in many good ways.
In this post, let’s append that method again here along with the two more methods to make the story complete.
public static void RawCreateProjectParameterFromExistingSharedParameter(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.Insert(def, binding, group);
}
public static void RawCreateProjectParameterFromNewSharedParameter(RvtApplication app, string defGroup, string name, ParameterType type, bool visible, CategorySet cats, BuiltInParameterGroup paramGroup, bool inst)
{
DefinitionFile defFile = app.OpenSharedParameterFile();
if (defFile == null) throw new Exception("No SharedParameter File!");
ExternalDefinition def = app.OpenSharedParameterFile().Groups.Create(defGroup).Definitions.Create(name, type, visible) as ExternalDefinition;
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.Insert(def, binding, paramGroup);
}
public static void RawCreateProjectParameter(RvtApplication app, string name, ParameterType type, bool visible, CategorySet cats, BuiltInParameterGroup group, bool inst)
{
//InternalDefinition def = new InternalDefinition();
//Definition def = new Definition();
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.Insert(def, binding, group);
}
It may be worth of a few more words about the third method. It creates a temporary shared parameter file and switch the current shared parameter file over regardless of what it is, creates the named shared parameter in a temporary DefinitionGroup, creates a type binding or instance binding accordingly for the shared parameter, adds the Binding to the BindingMap got from the ParameterBindings property of the Revit Document of concern, and finally switches back to the original shared parameter file.
The following test code can be used to exercise the help methods:
…
Category wall = CachedDoc.Settings.Categories.get_Item(BuiltInCategory.OST_Walls);
Category door = CachedDoc.Settings.Categories.get_Item(BuiltInCategory.OST_Doors);
CategorySet cats1 = CachedApp.Create.NewCategorySet();
cats1.Insert(wall);
cats1.Insert(door);
RawCreateProjectParameterFromExistingSharedParameter(CachedApp, "ExistingParameter1", cats1, BuiltInParameterGroup.PG_DATA, false);
RawCreateProjectParameterFromNewSharedParameter(CachedApp, "NewDefinitionGroup1", "NewParameter1", ParameterType.Text, true, cats1, BuiltInParameterGroup.PG_DATA, false);
RawCreateProjectParameter(CachedApp, "TemporarySharedParameter", ParameterType.Text, true, cats1, BuiltInParameterGroup.PG_DATA, true);
…
ProjectParameter Creator of Revit .NET Addin Wizard can help create the code automatically in a configurable and flexible way in a second.
Every time I try to do this I end up with a shared parameter. Can you tell me the "Trick" to creating the project parameter as project rather than shared?
Thanks
David
Posted by: A Facebook User | 02/08/2012 at 12:44 AM
"As can be seen from the Project Parameters dialog in Revit, project parameters can be defined from both ‘project parameters’ themselves and shared parameters.
The former is not achievable programmatically due to the fact that InternalDefinition or native Parameter cannot be created with the Revit API. Though there is an InternalDefinitions.Create() method in the API and it looks like being supposed to fulfill the task but the point is that nowhere and no way to get an instance of InternalDefinitions."
Posted by: Spiderinnet | 02/08/2012 at 01:03 AM
Hello!
We´re using Revit project-parameters to store meta informations of elements with Revit Architecture 2012. This snipped seemed very helpful to generate those parameters on the fly. Unfortunately, we weren´t able to get it fully running.
We´re using RawCreateProjectParameter for the project. The tempfile is created and replaced the old SharedParametersFilename correctly. But somehow NewTypeBinding respectively adding the type binding to ParameterBindings doesn´t have any effect.
For now, we`re creating the project parameters on the fly and add them manually to the current project. (Management -> Project Parameters)
Do you have any hint what could go wrong and how to fix this?
Posted by: Enno Boland | 05/21/2012 at 05:04 AM
Without seeing more details like code snippets, not exactly sure what might be going wrong on your side. The code worked well and didn't fail ever for me. Anyway, let me make a guess educationally.
1. A Transaction did not start before the method was being called, maybe?
2. CategorySet was not properly constructed?
3. The last argument to the method was not specified as FALSE if a TYPE project parameter was intended to be created?
4. The Project Parameter name was not specified as wanted by Revit?
Just tried something as follows and verified everthing was fine (BTW, I was using the same RAC 2012):
using (Transaction trans = new Transaction(CachedDoc, "CreateProjectParameters"))
{
trans.Start();
Category wall = CachedDoc.Settings.Categories.get_Item(BuiltInCategory.OST_Walls);
Category door = CachedDoc.Settings.Categories.get_Item(BuiltInCategory.OST_Doors);
CategorySet cats1 = CachedApp.Create.NewCategorySet();
cats1.Insert(wall);
cats1.Insert(door);
RawCreateProjectParameter(CachedApp, "PrjParameterForInstancesOfWallsAndDoors", ParameterType.Text, true, cats1, BuiltInParameterGroup.PG_DATA, true);
Category window = CachedDoc.Settings.Categories.get_Item(BuiltInCategory.OST_Windows);
CategorySet cats2 = CachedApp.Create.NewCategorySet();
cats2.Insert(window);
RawCreateProjectParameter(CachedApp, "PrjParameterForTypesOfWindows", ParameterType.Area, true, cats2, BuiltInParameterGroup.PG_AREA, false);
trans.Commit();
}
After the code is run on your side, you could see too that all walls and doors (not their TYPEs, please note) will have the first additional project parameter added, and the TYPE (not its instances, please note) of windows will have the second project parameter added.
Please give it a try and see how it works on your side this time and feel free to post any further comments back.
Posted by: Spiderinnet | 05/21/2012 at 10:38 PM