Hi,
based on a recent question I thought what is a simple working code structure to iterate and modify a cell content.
This topic was discussed several times, but usually for C++ API. And when for NET, not many clear answers were provided. Because C++ and NET APIs are implemented differently a bit (which makes sense, C++ iterator and C# enumerator are different animals ;-), so not everything can be copied 1:1.
I wrote two snippets, one inspired by Yongan.Fu's answer in this discussion, the second one put together from more sources. But they do not work :-(
Test workflow is based on the attached DGN:
- Identify an element from a cell (line string)
- Obtain a parent element (cell element header)
- Find a line that is in wrong level (level named "circles")
- Change the element level to the right one ("lines")
- Write the modification back to DGN file
Snippet 1:
Element parentElement = selected.ParentElement; CellHeaderElement cellToBeModified = parentElement as CellHeaderElement; CellHeaderElement originalCell = Element.GetFromElementRef(cellToBeModified.GetNativeElementRef()) as CellHeaderElement; ChildElementEnumerator children = new ChildElementEnumerator(cellToBeModified); while (children.MoveNext()) { if (children.Current is LineStringElement) { Element originalElement = Element.GetFromElementRef(children.Current.GetNativeElementRef()); ElementPropertiesGetter getter = new ElementPropertiesGetter(children.Current); if (getter.Level == this.levelCircle.LevelId) { ElementPropertiesSetter setter = new ElementPropertiesSetter(); setter.SetLevel(this.levelLines.LevelId); bool status = setter.Apply(children.Current); // true returned, instance changed // Bentley.DgnPlatformNET.DgnPlatformNETException: 'Bad StatusInt: 69645 // children.Current.ReplaceInModel(original); } } } // Test, whether modified cell was really modified ... not, it still contains original element cellToBeModified.ExposeChildren(ExposeChildrenReason.Query); bool exposeResult = cellToBeModified.ExposeChildren(ExposeChildrenReason.Query); ChildElementCollection childrens = cellToBeModified.GetChildren(); // Bentley.DgnPlatformNET.DgnPlatformNETException: 'Bad StatusInt: 32768' // cellToBeModified.ReplaceInModel(originalCell);
Snippet 2:
Element parentElement = selected.ParentElement; CellHeaderElement cellToBeModified = parentElement as CellHeaderElement; CellHeaderElement originalCell = Element.GetFromElementRef(cellToBeModified.GetNativeElementRef()) as CellHeaderElement; cellToBeModified.ExposeChildren(ExposeChildrenReason.Edit); bool exposeResult = cellToBeModified.ExposeChildren(ExposeChildrenReason.Edit); // true returned ChildElementCollection children = cellToBeModified.GetChildren(); foreach (Element component in children) { if (component is LineStringElement) { Element original = Element.GetFromElementRef(component.GetNativeElementRef()); ElementPropertiesGetter getter = new ElementPropertiesGetter(component); if (getter.Level == this.levelCircle.LevelId) { ElementPropertiesSetter setter = new ElementPropertiesSetter(); setter.SetLevel(this.levelLines.LevelId); bool status = setter.Apply(component); // Bentley.DgnPlatformNET.DgnPlatformNETException: 'Bad StatusInt: 69645' // component.ReplaceInModel(original); } } } // Bentley.DgnPlatformNET.DgnPlatformNETException: 'Bad StatusInt: 32768' // cellToBeModified.ReplaceInModel(originalCell);
I do not know whether I do not understand API right, so the code is wrong, or there is a bug in API implementation.
With regards,
Jan