We introduced some help methods in the previous article about how to address various FamilyParameter value setting scenarios. In this post, let’s see how to do so with some VB.NET extension methods to the family parameter class, FamilyParameter.
The following extension method will set a value regardless of data type to the calling FamilyParameter regarding the specified FamilyType in the specified FamilyManager:
<System.Runtime.CompilerServices.Extension()> _
Public Sub SetValue(ByVal fp As FamilyParameter, ByVal fm As FamilyManager, ByVal ft As FamilyType, 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
It pretty much does the same thing as the comprehensive help method introduced previously. Please just do not forget to copy them into a VB.NET module instead of a class. However, some questions may come in mind of some readers:
- Why must we provide the FamilyManager as an argument to these methods?
- Can a particular FamilyParameter instance belong to different FamilyManager objects?
- Can a specific FamilyType reside in multiple FamilyManager objects?
The answer to the first question is that we have to since the associated FamilyManager cannot be found anywhere either from the FamilyParameter or the FamilyType.
The answer to the last two is apparently the same, NO, but on the other hand the same FamilyParameter instance can be associated with some different FamilyType instances.
Anyway, it does not seem a big deal to always have the FamilyManager as an argument in these methods.
The following extension method will set a value regardless of data type to the calling FamilyParameter in case the name of the FamilyType of interest is known:
<System.Runtime.CompilerServices.Extension()> _
Public Sub SetValue(ByVal fp As FamilyParameter, ByVal fm As FamilyManager, ByVal familyTypeName As String, ByVal value As Object)
Dim FT__1 As FamilyType = (From ft In fm.Types).ToList().FirstOrDefault(Function(e) e.Name.Equals(familyTypeName, StringComparison.CurrentCultureIgnoreCase))
If FT__1 Is Nothing Then
Throw New Exception("Invalid Value Input!")
End If
fp.SetValue(fm, FT__1, value)
End Sub
Let’s do a bit more this time. How to set a value to a FamilyParameter of all FamilyType instances of the family document of interest represented by the FamilyManager?
It is very simple supposing the comprehensive one has already been there in the same place. Here it is:
<System.Runtime.CompilerServices.Extension()> _
Public Sub SetValue(ByVal fp As FamilyParameter, ByVal fm As FamilyManager, ByVal value As Object)
For Each ft As FamilyType In fm.Types
fp.SetValue(fm, ft, value)
Next
End Sub
By the way, please do not forget to put these extension methods into a module and import its namespace into the source that you are working on.
The following test code can be used to exercise these extension methods:
…
If CachedDoc.IsFamilyDocument Then
Dim fm As FamilyManager = CachedDoc.FamilyManager
Dim ft As FamilyType = RawConvertSetToList(Of FamilyType)(fm.Types)(0)
Dim urlFP As FamilyParameter = RawFindFamilyParameter(fm, "URL")
Dim legHeightFP As FamilyParameter = RawFindFamilyParameter(fm, "Leg Height")
Dim depthFP As FamilyParameter = RawFindFamilyParameter(fm, "Depth")
Dim the1stStringFP As FamilyParameter = RawConvertSetToList(Of FamilyParameter)(fm.Parameters).First(Function(e) e.StorageType = StorageType.String)
urlFP.SetValue(fm, "http://spiderinnet.typepad.com")
legHeightFP.SetValue(fm, ft, 1.11)
depthFP.SetValue(fm, ft, 2.22)
the1stStringFP.SetValue(fm, ft, "The first family parameter having the String StorageType.")
End If
…
FamilyParameter Writer of RevitAddinWizard can help do all of these in a configurable and flexible way in C# or VB.NET.
Recent Comments