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.
Q: Can we redefine an project parameter which is defined from a shared parameter?
A: Yes, supposing the shared parameter definition is still there in the DefinitionGroup and in turn in the DefinitionFile:
Public Shared Sub RawReplaceProjectParameterWithExistingSharedParameter(ByVal app As RvtApplication, ByVal name As String, ByVal cats As CategorySet, ByVal group As BuiltInParameterGroup, ByVal inst As Boolean)
Dim defFile As DefinitionFile = app.OpenSharedParameterFile()
If defFile Is Nothing Then
Throw New Exception("No SharedParameter File!")
End If
Dim v As List(Of Definition) = (From dg As DefinitionGroup In defFile.Groups From d In dg.Definitions Where d.Name = name)
If v Is Nothing OrElse v.Count() < 1 Then
Throw New Exception("Invalid Name Input!")
End If
Dim def As ExternalDefinition = v.First()
Dim binding As Autodesk.Revit.DB.Binding = app.Create.NewTypeBinding(cats)
If inst Then
binding = app.Create.NewInstanceBinding(cats)
End If
Dim map As BindingMap = (New UIApplication(app)).ActiveUIDocument.Document.ParameterBindings
map.ReInsert(def, binding, group)
End Sub
Q: Can we update the categories only of an existing project parameter regardless of where it is defined from (project or shared parameter)?
A: No. The following code tries its best but without any luck:
Public Shared Sub RawRecategorizeProjectParameter(ByVal doc As RvtDocument, ByVal name As String, ByVal cats As CategorySet)
Dim map As BindingMap = doc.ParameterBindings
Dim def As Definition = map.GetDefiniton(name)
Dim binding As Autodesk.Revit.DB.Binding = map.GetBinding(name)
If def Is Nothing OrElse binding Is Nothing Then
Return
End If
Dim oriCats As CategorySet = Nothing
If TryCast(binding, InstanceBinding) IsNot Nothing Then
oriCats = TryCast(binding, InstanceBinding).Categories
Else
oriCats = TryCast(binding, TypeBinding).Categories
End If
oriCats.Clear()
For Each cat As Autodesk.Revit.DB.Category In cats
oriCats.Insert(cat)
Next
map.ReInsert(def, binding)
End Sub
Q: Can we change the binding only of an existing project parameter?
A: No. The following code does not seem to have anything wrong but it just can not make the job done:
Public Shared Sub RawRebindProjectParameter(ByVal doc As RvtDocument, ByVal name As String, ByVal cats As CategorySet, ByVal group As BuiltInParameterGroup, ByVal inst As Boolean)
Dim map As BindingMap = doc.ParameterBindings
Dim def As Definition = map.GetDefiniton(name)
Dim binding As Autodesk.Revit.DB.Binding = doc.Application.Create.NewTypeBinding(cats)
If inst Then
binding = doc.Application.Create.NewInstanceBinding(cats)
End If
map.ReInsert(def, binding, group)
End Sub
Q: If the original shared parameter definition file is lost, can we redefine the corresponding shared project parameter?
A: 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 Shared Sub RawReplaceProjectParameterWithTempSharedParameter(ByVal app As RvtApplication, ByVal name As String, ByVal type As ParameterType, ByVal visible As Boolean, ByVal cats As CategorySet, ByVal group As BuiltInParameterGroup, _
ByVal inst As Boolean)
Dim oriFile As String = app.SharedParametersFilename
Dim tempFile As String = Path.GetTempFileName() & ".txt"
Using File.Create(tempFile)
End Using
app.SharedParametersFilename = tempFile
Dim def As ExternalDefinition = TryCast(app.OpenSharedParameterFile().Groups.Create("TemporaryDefintionGroup").Definitions.Create(name, type, visible), ExternalDefinition)
app.SharedParametersFilename = oriFile
File.Delete(tempFile)
Dim binding As Autodesk.Revit.DB.Binding = app.Create.NewTypeBinding(cats)
If inst Then
binding = app.Create.NewInstanceBinding(cats)
End If
Dim map As BindingMap = (New UIApplication(app)).ActiveUIDocument.Document.ParameterBindings
map.ReInsert(def, binding, group)
End Sub
Something might be with the GUID of the original shared parameter which was used to define the project parameter, but that is something deep enough which may need some more posts to discuss about in the future, e.g. how to retrieve the GUID out from a shared project parameter, and how to synchronize it between the project parameter and its original shared parameter.
The following code can test out 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)
'RawReplaceProjectParameterWithExistingSharedParameter(CachedApp, "ExistingParameter1", cats1, BuiltInParameterGroup.PG_DATA, False)
RawReplaceProjectParameterWithExistingSharedParameter(CachedApp, "ExistingParameter1", cats1, BuiltInParameterGroup.PG_IFC, True)
'RawReplaceProjectParameterWithTempSharedParameter(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 either in VB.NET or C#.
Recent Comments