Modifying string items in Property Definition List does not show in Properties Palette (*Error getting value*)

Modifying string items in Property Definition List does not show in Properties Palette (*Error getting value*)

tipitasa
Enthusiast Enthusiast
1,079 Views
6 Replies
Message 1 of 7

Modifying string items in Property Definition List does not show in Properties Palette (*Error getting value*)

tipitasa
Enthusiast
Enthusiast

Short: After progmatically updating the List Items in the List Definition of a Property Definition, the items in the Style Manager are correct, but the list of available values either does not update or shows *Error getting value*. I'm using the same code and sometimes get one and sometimes the other result.


Mostly, it helps to close the Properties Panel (to click on x, not just hide it) and reopen it and then the updated values show.
Sometimes it doesn't and then I have to Remove Property Set in GUI and then re-add it.

What am I missing? Is there a way to progmatically update/refresh/reload the PROPERTIES > Extended Data tab?

Photos:
I'm modifying the Property Set Definition called NVSurfaceStyles.
Property Definition called SurfaceStyle has a source ListDefinition SurfaceStyles-NV.
All is OK in Style Manager.

Screenshot 2023-06-27 134517.png

Screenshot 2023-06-27 134609.png

Screenshot 2023-06-27 135043.png

Screenshot 2023-06-27 135131.png

The code that I'm using:

 

using Autodesk.Aec.DatabaseServices;
using Autodesk.Aec.PropertyData.DatabaseServices;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;

using System.Collections.Generic;

using ObjectId = Autodesk.AutoCAD.DatabaseServices.ObjectId;
        Database _db = Application.DocumentManager.MdiActiveDocument.Database;

        internal void ImportStyleNamesToPropertySetListDefinitions()
        {
            ObjectId propertySetDefinitionId = ObjectId.Null;
            List<string> stylesToAdd = new List<string>();

            using (var tr = _db.TransactionManager.StartTransaction())
            {
                // open property set definition
                var propSetDef = tr.GetObject(propertySetDefinitionId, OpenMode.ForWrite) as PropertySetDefinition;

                // for each of the definitions in it
                foreach (PropertyDefinition propDefinition in propSetDef.Definitions)
                {
                    // go by name
                    if (propDefinition.Name == "SurfaceStyle")
                    {
                        if (propDefinition.DataType == Autodesk.Aec.PropertyData.DataType.List)
                        {
                            // get source list definition id
                            var listDefinitionId = propDefinition.ListDefinitionId;

                            // open this list definition
                            var listDefinition = tr.GetObject(listDefinitionId, OpenMode.ForWrite) as ListDefinition;

                            // add style name items to it
                            foreach (string styleName in stylesToAdd)
                                listDefinition.AddListItem(styleName);
                        }
                    }
                    
                }
                tr.Commit();
            }

 

 

protected void ClearPropertyListDefinitions(ObjectId propertySetDefinitionId)
        {
            using (var tr = _db.TransactionManager.StartTransaction())
            {
                // open property set definition
                var propSetDef = tr.GetObject(propertySetDefinitionId, OpenMode.ForRead) as PropertySetDefinition;

                // for each of the definitions in it
                foreach (PropertyDefinition propDefinition in propSetDef.Definitions)
                {
                    // find correct property definitions
                    if (propDefinition.Name == "SurfaceStyle")
                    {
                        if (propDefinition.DataType == Autodesk.Aec.PropertyData.DataType.List)
                        {
                            // get source list definition id
                            var listDefinitionId = propDefinition.ListDefinitionId;

                            // open source list definition
                            var listDefinition = tr.GetObject(listDefinitionId, OpenMode.ForWrite) as ListDefinition;

                            // clear items that are not "-"
                            ObjectIdCollection itemIds = listDefinition.GetListItems();
                            for (int i = itemIds.Count - 1; i >= 0; i--)
                            {
                                var item = tr.GetObject(itemIds[i], OpenMode.ForWrite) as ListItem;
                                if (item.Name != "-")
                                    listDefinition.DeleteListItem(itemIds[i]);
                            }
                        }
                    }
                }
                tr.Commit();
            }



0 Likes
Accepted solutions (1)
1,080 Views
6 Replies
Replies (6)
Message 2 of 7

Gepaha
Collaborator
Collaborator

I responded to the other post.
From the images I assume you are using Civil 3D.
I have ACA/MEP, I don't have Civil 3D installed.
So I can't test this in Civil 3D.

Code that I have tested and for me it works correctly. Note that I added propDefinition.SubSetDatabaseDefaults(db);

 

 

        public static void ModifyListDefinitionFromPropertySetDefinition()
        {
            Database db = Application.DocumentManager.MdiActiveDocument.Database;

            string propSetDefName = "MyPropertySetDefinition";
            List<string> stylesToAdd = new List<string>(){"First", "Second", "Third"};

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DictionaryPropertySetDefinitions psdDict = new DictionaryPropertySetDefinitions(db);

                if (psdDict.Has(propSetDefName, tr))
                {
                    AcDb.ObjectId propSetDefId = psdDict.GetAt(propSetDefName);                   

                    // open property set definition
                    var propSetDef = tr.GetObject(propSetDefId, OpenMode.ForWrite) as PropertySetDefinition;

                    // for each of the definitions in it
                    foreach (PropertyDefinition propDefinition in propSetDef.Definitions)
                    {
                        // go by name
                        if (propDefinition.Name == "SomeName")
                        {
                            if (propDefinition.DataType == Autodesk.Aec.PropertyData.DataType.List)
                            {
                                // get source list definition id
                                var listDefinitionId = propDefinition.ListDefinitionId;

                                // open this list definition
                                var listDefinition = tr.GetObject(listDefinitionId, OpenMode.ForWrite) as ListDefinition;

                                // add style name items to it
                                foreach (string styleName in stylesToAdd)
                                    listDefinition.AddListItem(styleName);

                                propDefinition.SubSetDatabaseDefaults(db);
                                tr.Commit();
                            }
                        }                       
                    }
                }               
            }
        }

 

 

0 Likes
Message 3 of 7

tipitasa
Enthusiast
Enthusiast

I'll just reply here, as my current issue is connected with the title of this post. And I'll link the other one here for reference.

Actually Adding the List Items works for me too.
But removing does not - did you also try removing by calling: 

                            ObjectIdCollection itemIds = listDefinition.GetListItems();
                            for (int i = itemIds.Count - 1; i >= 0; i--)
                            {
                                var item = tr.GetObject(itemIds[i], OpenMode.ForWrite) as ListItem;
                                if (item.Name != "-")
                                {
                                    listDefinition.DeleteListItem(itemIds[i]);
                                }
                            }

 

 I also tried by removing all items from the list and then re-adding "-". (as this is the default value that I'd like to keep).

The first time this runs, it produces the *Error getting value* message, even though nothing in the code fails.
Then, I manually remove and add back the same Property Set to the selected surface.
And after, the same code runs correctly.

0 Likes
Message 4 of 7

Gepaha
Collaborator
Collaborator
Accepted solution

I tested your code and it works correctly for me.
Regarding the error message "*Error getting value*" in the "Properties Extended Data" tab, you will always receive if an item from ListDefinition that is in use is deleted via code. In principle you could not delete a value in use. I would have to first change the value and then delete it.
Note that if you try to remove an item in use through "StyleManager>Multi-Potpose Objects>List Definitions" it will not be possible because the remove button will not be enabled.

The *Error getting value* when deleting an item in use via code:

gphanauer_0-1687970709472.png

When an item is in use, it cannot be removed:

gphanauer_1-1687971023116.png

 

 

 

0 Likes
Message 5 of 7

tipitasa
Enthusiast
Enthusiast

That was exactly it, so thank you. I didn't think about the connection of Property Set Value on a surface and that same List Item in the List Definition, I saw it only as a 'free floating' string.

What I do now is, that I progmatically remove and re-add the Property Set to each surface that was using the cleared ListDefinition and assign the correct property values.

0 Likes
Message 6 of 7

Gepaha
Collaborator
Collaborator

If you rename a ListDefinition item then all Property Sets that use this item will reflect the renamed item.
I have never used Civil 3D but there is some content from Autodesk University that might help. It makes use of VBScript and at the end of a plug-in written in .NET which is not exposed.

https://www.autodesk.com/autodesk-university/class/Using-Automation-Civil-3D-Construction-Documentat... 
If possible expose your solutions here because it helps for me and others.

0 Likes
Message 7 of 7

tipitasa
Enthusiast
Enthusiast

That's a good note.

What I did is, that I call this next method after the closing } of the Transaction using in the ClearPropertyListDefinition().

RebuildSurfacesWithUpdatedPropertySet(propertySetDefinitionId, clearSurfaceStyles);


 So as a whole, both together:

        protected void ClearPropertyListDefinitions(ObjectId propertySetDefinitionId, bool clearSurfaceStyles)
        {
            using (var tr = _db.TransactionManager.StartTransaction())
            {
                // open property set definition
                var propSetDef = tr.GetObject(propertySetDefinitionId, OpenMode.ForRead) as PropertySetDefinition;

                // for each of the definitions in it
                foreach (PropertyDefinition propDefinition in propSetDef.Definitions)
                {
                    // find correct property definitions
                    if (clearSurfaceStyles && propDefinition.Name == "SurfaceStyle")
                    {
                        if (propDefinition.DataType == Autodesk.Aec.PropertyData.DataType.List)
                        {
                            // get source list definition id
                            var listDefinitionId = propDefinition.ListDefinitionId;

                            // open source list definition
                            var listDefinition = tr.GetObject(listDefinitionId, OpenMode.ForWrite) as ListDefinition;

                            // clear items that are not "-"
                            ObjectIdCollection itemIds = listDefinition.GetListItems();
                            for (int i = itemIds.Count - 1; i >= 0; i--)
                            {
                                var item = tr.GetObject(itemIds[i], OpenMode.ForWrite) as ListItem;
                                if (item.Name != "-")
                                    listDefinition.DeleteListItem(itemIds[i]);
                            }
                        }
                    }
                }
                tr.Commit();
            }
			
			RebuildSurfacesWithUpdatedPropertySet(propertySetDefinitionId, clearSurfaceStyles);
		}
       /**
         * if a surface was using a deleted list item in it's property set value
         * it produces a display of *Error getting value* in the Extended Data on GUI
         * 
         * Take all tin surfaces in the drawing
         * that use the property set definition by propertySetDefinitionId
         * that had it's list items deleted.
         * 
         * Depending on the values of the booleans
         *   - clearedSurfaceStyles
         *   - clearedProfileStyles
         *   - clearedSectionStyles
         * if true use a default "-"  
         * else remember the previously set value of the property
         * then remove property set from the surface
         * re-add it
         * apply correct property values
         */
        protected void RebuildSurfacesWithUpdatedPropertySet(ObjectId propSetDefintionId, bool clearedSurfaceStyles)
        {
            var surfaceIds = Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument.GetSurfaceIds();
			CQAecSurfaceTools.GetTinSurfaceIds();   
            PropertySet modifiedPropSet = null;
            using (var tr = _db.TransactionManager.StartTransaction())
            {
                foreach (var surfaceId in surfaceIds)
                {
                    var surface = tr.GetObject(surfaceId, OpenMode.ForWrite);

                    ObjectIdCollection propSetIds = PropertyDataServices.GetPropertySets(surface);
                    foreach (ObjectId propSetId in propSetIds)
                    {
                        try
                        {
                            // does it use the property set definition in question
                            PropertySet propSet = tr.GetObject(propSetId, OpenMode.ForWrite) as PropertySet;
                            if (propSet.PropertySetDefinition == propSetDefintionId)
                            {
                                modifiedPropSet = propSet;
                                break;
                            }
                        }
                        catch { }
                    }

                    // remember property values
                    string surfaceStylePropValue = (clearedSurfaceStyles) ? "-" : (string)modifiedPropSet.GetAt(modifiedPropSet.PropertyNameToId("SurfaceStyle"));
                    string surfaceName = "";
                    try
                    {
                        surfaceName = (string)modifiedPropSet.GetAt(modifiedPropSet.PropertyNameToId("SurfaceName"));
                    }
                    catch { }

                    // remove property set
                    PropertyDataServices.RemovePropertySet(surface, propSetDefintionId);

                    // re-add property set
                    PropertyDataServices.AddPropertySet(surface, propSetDefintionId);

                    // add property values
                    propSetIds = PropertyDataServices.GetPropertySets(surface);
                    foreach (ObjectId propSetId in propSetIds)
                    {
                        try
                        {
                            PropertySet reAddedPropSet = tr.GetObject(propSetId, OpenMode.ForRead) as PropertySet;
                            if (reAddedPropSet.PropertySetDefinition == propSetDefintionId)
                            {
                                reAddedPropSet.UpgradeOpen();
                                reAddedPropSet.SetAt(reAddedPropSet.PropertyNameToId("SurfaceName"), surfaceName);
                                reAddedPropSet.SetAt(reAddedPropSet.PropertyNameToId("SurfaceStyle"), surfaceStylePropValue);
                                break;
                            }
                        }
                        catch { }
                    }

                    surface.DowngradeOpen();
                }
                tr.Commit();
            }
        }

 

0 Likes