Problem changing element BuiltInParameter

Problem changing element BuiltInParameter

2lenin-off
Enthusiast Enthusiast
473 Views
3 Replies
Message 1 of 4

Problem changing element BuiltInParameter

2lenin-off
Enthusiast
Enthusiast

Hello! I have a problem with changing element parameters

 

public partial class FormChageLevel : Window
{
    private Document _doc;
    public Dictionary<string, List<Element>> ElementsByLevel { get; set; }

    public FormChageLevel(Document document)
    {
        _doc = document;
        InitializeComponent();
        ElementsByLevel = GetElementsByLevel(_doc);
        this.DataContext = this;
    }
...

 

I have a function that creates a Dictionary: a level and all the elements on it.

 

        public Dictionary<string, List<Element>> GetElementsByLevel(Document doc)
        {
            Dictionary<string, List<Element>> elementsByLevel = new Dictionary<string, List<Element>>();
            FilteredElementCollector collector = new FilteredElementCollector(doc);
            List<Level> levels = collector.OfClass(typeof(Level)).Cast<Level>().ToList();
            foreach (Level level in levels)
            {
                List<Element> elementInLevel = new List<Element>();
                ElementLevelFilter levelFilter = new ElementLevelFilter(level.Id);
                FilteredElementCollector elementsList = new FilteredElementCollector(doc);
                List<Element> elements = elementsList.WherePasses(levelFilter).ToList();
                foreach (Element element in elements)
                {
                    elementInLevel.Add(element);
                }
                elementsByLevel.Add(level.Name, elementInLevel);
            }
            return elementsByLevel;
        }

 

I also have a function that returns an array of BuiltInParamete, depending on the category (in progress)

 

        public static BuiltInParameter[] GetParametersForMovingItems(Element element)
        {
            string category = element.Category.Name;
            BuiltInParameter[] parameters;
            BuiltInParameter baseLevel;
            BuiltInParameter baseOffset; 
            BuiltInParameter topLevel;
            BuiltInParameter topOffset;
            if (category == "OST_Walls")
            {
                baseLevel = BuiltInParameter.WALL_BASE_CONSTRAINT;
                baseOffset = BuiltInParameter.WALL_BASE_OFFSET;
                topLevel = BuiltInParameter.WALL_HEIGHT_TYPE;
                topOffset = BuiltInParameter.WALL_TOP_OFFSET;
                parameters = new BuiltInParameter[] { baseLevel, baseOffset, topLevel, topOffset };
            }
            else if (category == "OST_StructuralColumns")
            {
                baseLevel = BuiltInParameter.FAMILY_BASE_LEVEL_PARAM;
                baseOffset = BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM;
                topLevel = BuiltInParameter.FAMILY_TOP_LEVEL_PARAM;
                topOffset = BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM;
                parameters = new BuiltInParameter[] { baseLevel, baseOffset, topLevel, topOffset };
            }
            else if (category == "OST_Floors")
            {
                baseLevel = BuiltInParameter.LEVEL_PARAM;
                baseOffset = BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM;
                parameters = new BuiltInParameter[] { baseLevel, baseOffset };
            }
            else if (category == "OST_Ceilings")
            {
                baseLevel = BuiltInParameter.LEVEL_PARAM;
                baseOffset = BuiltInParameter.CEILING_HEIGHTABOVELEVEL_PARAM;
                parameters = new BuiltInParameter[] { baseLevel, baseOffset };
            }
            else if (category == "OST_Roofs")
            {
                baseLevel = BuiltInParameter.ROOF_BASE_LEVEL_PARAM;
                baseOffset = BuiltInParameter.ROOF_LEVEL_OFFSET_PARAM;
                parameters = new BuiltInParameter[] { baseLevel, baseOffset };
            }
            else if (category == "OST_Windows" || category == "OST_Doors")
            {
                baseLevel = BuiltInParameter.FAMILY_LEVEL_PARAM;
                baseOffset = BuiltInParameter.INSTANCE_SILL_HEIGHT_PARAM;
                parameters = new BuiltInParameter[] { baseLevel, baseOffset };
            }
            else if (category == "OST_Stairs" || category == "OST_Ramps")
            {
                baseLevel = BuiltInParameter.STAIRS_BASE_LEVEL_PARAM;
                baseOffset = BuiltInParameter.STAIRS_BASE_OFFSET;
                topLevel = BuiltInParameter.STAIRS_TOP_LEVEL_PARAM;
                topOffset = BuiltInParameter.STAIRS_TOP_OFFSET;
                parameters = new BuiltInParameter[] { baseLevel, baseOffset, topLevel, topOffset };
            }
            else if (category == "OST_StairsRailing")
            {
                baseLevel = BuiltInParameter.STAIRS_RAILING_BASE_LEVEL_PARAM;
                baseOffset = BuiltInParameter.STAIRS_RAILING_HEIGHT_OFFSET;
                parameters = new BuiltInParameter[] { baseLevel, baseOffset };
            }
            else
            {
                baseLevel = BuiltInParameter.FAMILY_LEVEL_PARAM;
                baseOffset = BuiltInParameter.INSTANCE_ELEVATION_PARAM;
                parameters = new BuiltInParameter[] { baseLevel, baseOffset };
            }
            return parameters;
        }

 

However, when running TransferringElementsToAnotherLevel() there is an error that levelParameter.Set("TEST") is read-only

 

     public void TransferringElementsToAnotherLevel()
        {
            string exportLevelName = LevelExport.SelectedItem as string;
            string importLevelName = levelImport.SelectedItem as string;
            var transaction = new Transaction(_doc, "Test");        
                transaction.Start();
                foreach (Element element in ElementsByLevel[exportLevelName])
                {
                    BuiltInParameter[] levelExportParametrs = CommandChangeLevel.GetParametersForMovingItems(element);
                    var levelParameter = element.get_Parameter(levelExportParametrs[0]);
                        if (levelParameter?.HasValue == true)
                        {
                            var oldLevel = _doc.GetElement(levelParameter.AsElementId()) as Level;
                            levelParameter.Set(importLevelName);
                        }
                }
                transaction.Commit();           
        }

 

 Thank you in advance for your assistance!

0 Likes
Accepted solutions (1)
474 Views
3 Replies
Replies (3)
Message 2 of 4

jeremy_tammik
Alumni
Alumni

Looks complicated. Does it work in a simpler context?

  

I would replace the dictionary of elements by a dictionary of ElementId instead. The Element objects may go out ot scope. It is safer to just use the element id and pass it in to doc.GetElement to ensure that yiou have fresh valid Element objects.

   

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 3 of 4

2lenin-off
Enthusiast
Enthusiast

Thanks for the answer. It didn’t work in a simpler context either, but it seems I found the cause of the error.

How can I ignore objects with "IsReadOnly = True" attribute and empty SuperComponent value through a filter?

0 Likes
Message 4 of 4

jeremy_tammik
Alumni
Alumni
Accepted solution

Maybe you can use RevitLookup or some other database exploration method to determine which built-in parameter holds the value of IsReadOnly and implement a parameter filter to handle that criterion.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open