We talked about creating new FamilyParameter instances before. Now let’s see how to create a shared FamilyParameter programmatically with VB.NET, which is converted from an existing Shared Parameter.
Before creating the specific code for the SharedParameter to FamilyParameter Converter, we need to put some Coders together first that we introduced and demonstrated before. They will save us a lot of precious time and avoid duplicate efforts.
Revit Parameter Organizer can organize various Revit parameters such as Shared Parameters, Family Parameters, Project Parameters and Built-in Parameter in many good ways.
Here they are:
#Region "From FamilyParameter Creator"
Public Shared Function RawConvertSetToList(Of T)(ByVal setVar As IEnumerable) As List(Of T)
Dim list As List(Of T) = (From p In setVar Select p)
Return List
End Function
Public Shared Function RawFindFamilyParameter(ByVal fm As FamilyManager, ByVal parameterName As String) As FamilyParameter
Dim fp As FamilyParameter = RawConvertSetToList(Of FamilyParameter)(fm.Parameters).FirstOrDefault(Function(e) e.Definition.Name.Equals(parameterName, StringComparison.CurrentCultureIgnoreCase))
If fp Is Nothing Then
Throw New Exception("Invalid ParameterName Input!")
End If
Return fp
End Function
Public Shared Function RawFindFamilyType(ByVal fm As FamilyManager, ByVal familyTypeName As String) As FamilyType
Dim famType As FamilyType = RawConvertSetToList(Of FamilyType)(fm.Types).FirstOrDefault(Function(e) e.Name.Equals(familyTypeName, StringComparison.CurrentCultureIgnoreCase))
If famType Is Nothing Then
Throw New Exception("Invalid FamilyTypeName Input!")
End If
Return famType
End Function
Public Shared Sub RawSetFamilyParameterValue(ByVal fm As FamilyManager, ByVal familyTypeName As String, ByVal parameterName As String, ByVal value As Object)
RawSetFamilyParameterValue(fm, RawFindFamilyType(fm, familyTypeName), RawFindFamilyParameter(fm, parameterName), value)
End Sub
Public Shared Sub RawSetFamilyParameterValue(ByVal fm As FamilyManager, ByVal ft As FamilyType, ByVal parameterName As String, ByVal value As Object)
RawSetFamilyParameterValue(fm, ft, RawFindFamilyParameter(fm, parameterName), value)
End Sub
Public Shared Sub RawSetFamilyParameterValue(ByVal fm As FamilyManager, ByVal familyTypeName As String, ByVal fp As FamilyParameter, ByVal value As Object)
RawSetFamilyParameterValue(fm, RawFindFamilyType(fm, familyTypeName), fp, value)
End Sub
Public Shared Sub RawSetFamilyParameterValue(ByVal fm As FamilyManager, ByVal ft As FamilyType, ByVal fp As FamilyParameter, ByVal value As Object)
Dim curFamType As FamilyType = fm.CurrentType
fm.CurrentType = ft
Try
Select Case fp.StorageType
Case StorageType.None
Exit Select
Case StorageType.Double
If value.GetType().Equals(GetType(String)) Then
fm.Set(fp, Double.Parse(TryCast(value, String)))
Else
fm.Set(fp, Convert.ToDouble(value))
End If
Exit Select
Case StorageType.Integer
If value.GetType().Equals(GetType(String)) Then
fm.Set(fp, Integer.Parse(TryCast(value, String)))
Else
fm.Set(fp, Convert.ToInt32(value))
End If
Exit Select
Case StorageType.ElementId
If value.GetType().Equals(GetType(Autodesk.Revit.DB.ElementId)) Then
fm.Set(fp, TryCast(value, Autodesk.Revit.DB.ElementId))
ElseIf value.GetType().Equals(GetType(String)) Then
fm.Set(fp, New Autodesk.Revit.DB.ElementId(Integer.Parse(TryCast(value, String))))
Else
fm.Set(fp, New Autodesk.Revit.DB.ElementId(Convert.ToInt32(value)))
End If
Exit Select
Case StorageType.String
fm.Set(fp, value.ToString())
Exit Select
End Select
Catch
Throw New Exception("Invalid Value Input!")
Finally
fm.CurrentType = curFamType
End Try
End Sub
#End Region
With all the above code handy, it becomes a pretty easy task to create some code to convert a Shared Parameter definition in an existing external DefinitionFile to a FamilyParameter in a particular Revit Family Document (Manager):
Public Shared Function RawFindExternalDefinition(ByVal defFile As DefinitionFile, ByVal name As String) As ExternalDefinition
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
Return Nothing
Else
Return v.First()
End If
End Function
Public Shared Sub ConvertSharedParameterToFamilyParameter(ByVal extDef As ExternalDefinition, ByVal famMan As FamilyManager, ByVal instance As Boolean, ByVal type As String, ByVal value As Object)
Dim fp As FamilyParameter = famMan.AddParameter(extDef, extDef.ParameterGroup, instance)
If value IsNot Nothing Then
RawSetFamilyParameterValue(famMan, type, fp, value)
End If
End Sub
A few points may be worth of mentioning here:
• The ParameterGroup of the new FamilyParameter will use the same one as in the Shared Parameter ExternalDefinition. If it needs to be overridden the converters can be easily to be extended to do so.
• The newly created FamilyParameter can be either instance applicable or type applicable.
• The newly created FamilyParameter can have a default value for a specific FamilyType. If it is not necessary, the arguments and the value assignment code can be removed without any negative impact.
The following test code can exercise the methods:
Dim extdef As ExternalDefinition = RawFindExternalDefinition(CachedApp.OpenSharedParameterFile(), "Area41")
ConvertSharedParameterToFamilyParameter(extdef, CachedDoc.FamilyManager, False, "Type 1", "0.00")
In terms of details of the various coders referenced in this post please refer to previous posts for ideas and code examples in either VB.NET or C#.
SharedParameter to FamilyParameter Converter of RevitAddinCoder can create all these in a second.
Recent Comments