Conversion from Deprecated FamilyManager.AddParameter

Conversion from Deprecated FamilyManager.AddParameter

stephen_harrison
Advocate Advocate
1,620 Views
5 Replies
Message 1 of 6

Conversion from Deprecated FamilyManager.AddParameter

stephen_harrison
Advocate
Advocate

Thanks to the help provided in an earlier post I thought I was getting my head around converting from Deprecated ParameterType to ForgeTypeId for Revit 2022 Api. Unfortuetly however I am having difficulties understanding how I would add a Family Parameter.

I understand that the new format is as follows;

 

FamilyManager.AddParameter(paramName, ForgeTypeId, ForgeTypeId, true);

 

However my issue is around the fact that my old code relied on making selections and the text of these selections was then converted to the respective BuiltInParameterGroup and ParameterType.

I am struggling to understand how the same would happen for the respective ForgeTypeId groupTypeId and ForgeTypeId specTypeId.

 

For example I select from my Group Parameter under: drop down “Dimensions” this has a respective BuiltInParameterGroup of “PG_Geometry” which intern in Revit 2022 would be represented by GroupTypeId.Geometry. How do I achieve this for the two respective ForgeTypeId?

 

Thank you in advance for any assistance.

Accepted solutions (2)
1,621 Views
5 Replies
Replies (5)
Message 2 of 6

RPTHOMAS108
Mentor
Mentor
Accepted solution

All you really need to do is fill your items control with objects containing each ForgeTypeId from

SpecUtils.GetAllSpecs
ParameterUtils.GetAllBuiltInGroups

 

Then for each such object you can override ToString with the following:
LabelUtils.GetLabelForGroup(ForgeTypeId)
LabelUtils.GetLabelForSpec(ForgeTypeId)


Pointing to the ForgeTypeId stored on that object

 

Or instead of using ToString you could create a property for the above which is used for the DisplayMember or Binding path.


In the end because your items control contains these objects with ForgeTypeIds you can get the selected item and feed it's ForgeTypeId property into the new function.

 

You would have to check if the specs/groups are suitable for creating parameters, that may not be the case. Some are perhaps used in internal parameters only.

 

    'UNTESTED!!!
    Public Class ForgeTypeIdDisplayItem
        'Reassign Document property at moment required
        'Only required for getting readable name of category
        Public Shared Document As Document = Nothing
        Public Property Id As ForgeTypeId = Nothing

        Public Sub New()
        End Sub
        Public Sub New(BIP As BuiltInParameter)
            Id = ParameterUtils.GetParameterTypeId(BIP)
        End Sub
        Public Sub New(BIPG As BuiltInParameterGroup)
            Id = ParameterUtils.GetParameterGroupTypeId(BIPG)
        End Sub

        Private Function IntGetDisplayValue() As String
            If Id Is Nothing Then
                Return Nothing
            End If

            If SpecUtils.IsSpec(Id) Then
                Return LabelUtils.GetLabelForSpec(Id)
            ElseIf UnitUtils.IsUnit(Id) Then
                Return LabelUtils.GetLabelForUnit(Id)
            ElseIf Category.IsBuiltInCategory(Id) Then
                Dim C = Category.GetBuiltInCategory(Id)
                If Document IsNot Nothing Then
                    Return Category.GetCategory(Document, C)?.Name
                Else
                    Return [Enum].GetName(GetType(BuiltInCategory), C)
                End If
            ElseIf ParameterUtils.IsBuiltInGroup(Id) Then
                Return LabelUtils.GetLabelForGroup(Id)

            ElseIf ParameterUtils.IsBuiltInParameter(Id) Then
                Return LabelUtils.GetLabelForBuiltInParameter(Id)
            Else
                Throw New Exception("Unknown ForgeTypeId")
            End If

        End Function
        Public Overrides Function ToString() As String
            Return IntGetDisplayValue()
        End Function


        Public Shared Function GetAllDisplaySpecs() As ForgeTypeIdDisplayItem()
            Dim Items = SpecUtils.GetAllSpecs()

            Dim Out = From x As ForgeTypeId In Items
                      Select New ForgeTypeIdDisplayItem With {.Id = x}

            Return Out.OrderBy(Function(j) j.ToString).ToArray

        End Function
        Public Shared Function GetAllBuiltInParameters() As ForgeTypeIdDisplayItem()
            Dim Items = ParameterUtils.GetAllBuiltInParameters

            Dim Out = From x As ForgeTypeId In Items
                      Select New ForgeTypeIdDisplayItem With {.Id = x}

            Return Out.OrderBy(Function(j) j.ToString).ToArray

        End Function
        Public Shared Function GetAllBuiltInParametersGroups() As ForgeTypeIdDisplayItem()
            Dim Items = ParameterUtils.GetAllBuiltInGroups

            Dim Out = From x As ForgeTypeId In Items
                      Select New ForgeTypeIdDisplayItem With {.Id = x}

            Return Out.OrderBy(Function(j) j.ToString).ToArray

        End Function


        Public Shared Operator =(Left As ForgeTypeIdDisplayItem, Right As ForgeTypeIdDisplayItem) As Boolean
            Return Left.Id = Right.Id
        End Operator
        Public Shared Operator <>(Left As ForgeTypeIdDisplayItem, Right As ForgeTypeIdDisplayItem) As Boolean
            Return Left.Id <> Right.Id
        End Operator
    End Class

 

 

 

0 Likes
Message 3 of 6

stephen_harrison
Advocate
Advocate

Thank you for tour response I will hopefully have chance to try it out over the weekend once I've converted to C#.

I note however that the solution utilises the following,  both of which have also been Deprecated ?

Id = ParameterUtils.GetParameterTypeId(BIP)

Id = ParameterUtils.GetParameterGroupTypeId(BIPG)

 Is there not a solution that doesn't utilise deprecated code?

0 Likes
Message 4 of 6

RPTHOMAS108
Mentor
Mentor

I believe you are using an older Revit build. The obsolete attribute on those things was remove from latest, so you would not be getting that notification.

 

Regardless you see the way it is heading so you should be switching to ForgeTypeIds where possible. I only really included those constructors to show the current things available.

 

The other thing I should mention is there are more built-in categories than document categories so wouldn't 100% trust what I've done above to get the display name of a built-in category (some categories for built-in categories will not be found).

0 Likes
Message 5 of 6

stephen_harrison
Advocate
Advocate

Thank you for your feedback, I have now had some time to examine and work with your suggestions and found it most helpful. Thankyou.

I have been unable to find a way of reducing the number specs/groups to match to those suitable for creating shared parameters so in order to test the code out I have hard coded the groups into my dropdown. Not ideal!

Everything appears to be working with one exception regarding shared parameters of type FamilyType when reading the shared parameters external definition file I am unable to retrieve the DATACATEGORY which in turn identifies the Family Type Category.

Any Ideas on how to retrieve the category and then how to convert the category identifier as a ForgeTypeId?

Thanks again for your assistance it is much appreciated.

0 Likes
Message 6 of 6

stephen_harrison
Advocate
Advocate
Accepted solution

The method of adding a FamilyType parameters is as follows:

 

FamilyParameter AddParameter(string parameterName, ForgeTypeId groupTypeId, Category familyCategory, bool isInstance);

 

So the question is how to get the category identifier as a ForgeTypeId?  Unfortuetly there is no 

CategoryTypeId class similar to SpecTypeId or UnitTypeId, but you can use these two functions to exchange a BuiltInCategory enumeration value for the equivalent ForgeTypeId:

 

 

Category.GetCategory(doc, Category.GetBuiltInCategory(specForgeTypeId)