Search code examples
.netschemabuilt-inilistrevit

How to Write to a schema a Revit Built-In Category list, when the builtInCategory type is not allowed


The line of code where the fieldbuilder is constructed assigns a type that can be stored as a string, int, XYZ etc.

The developer documentation doesn't include the "BuiltInCategory" type. I need to write this List<BuiltInCategory> to the "projectinfo object" for storage. Do I need to cast the List<BuiltinCategory> to a string List<string> for storage and then convert back for retrieval? Will that work?

public void StoreDataInProjectInfo(Document doc, Element projectInfoElement)
    {
        Schema schema = Schema.Lookup(SchemaGuid);

        IList<BuiltInCategory> BuiltincatStringList = new List<BuiltInCategory>();

        BuiltincatStringList.Add("1");
        BuiltincatStringList.Add("2");


        using (Transaction transEstorage = new Transaction(doc))
        {
            transEstorage.Start("add estorage list");


        if (null == schema)
        {
            SchemaBuilder sb = new SchemaBuilder(new Guid("AF5E4C3E-C2E2-493B-8236-BA0F5E323887"));

            //public accesibility
            sb.SetReadAccessLevel(AccessLevel.Public);
            sb.SetWriteAccessLevel(AccessLevel.Public);

This is the fieldbuilder list that needs a type the code fails on execution and reports an incorrect "type."

            //Storage Filled for Cat List
            ***FieldBuilder fb = sb.AddArrayField("UserCategoryList", typeof(BuiltInCategory))***; 




            fb.SetDocumentation("A Set Of Categories to be worksetted");

            //set schema name and register
            sb.SetSchemaName("UserCategoryList");
            schema = sb.Finish();
        }


        // Create an entity (object) for this schema (class) 
        Entity entity = new Entity(schema);

        // Get the field from the schema 
        Field userWSCategoryList = schema.GetField("UserCategoryList");

        entity.Set<IList<BuiltInCategory>>(userWSCategoryList, BuiltincatStringList);


        //Entity storage on Element
        projectInfoElement.SetEntity(entity);



        // Read back the data from the wall 
        Entity retrievedEntity = projectInfoElement.GetEntity(schema);

        IList<BuiltInCategory> retrievedData = retrievedEntity.Get<List<BuiltInCategory>>(schema.GetField("UserCategoryList"));


        transEstorage.Commit();
            }

    }

Solution

  • I'd recommend casting the BuiltInCategory to an int. This converts the BuiltInCategory to its underlying element ID value.

    This should be pretty straightforward - simply replace all instances of BuiltInCategory in your code above with int.

    To cast a BuiltInCategory to an int:

    BuiltInCategory builtInCategory;
    int builtInCategoryId = (int)builtInCategory;
    

    And the other way:

    BuiltInCategory builtInCategory = (BuiltInCategory)builtInCategoryId;
    

    This will be more consistent than trying to convert values to a string. If you ever have to deal with multiple languages in your code, you would likely run into issues using a string.