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 (simplified versions, e.g. without proper disposal, are shared), 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:
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(originalElement); } } } // 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
N014 cell modification.dgn
Hi Jan Šlegr,
I will see if I (or possibly YongAn) can make some time to review your test case above and reply back with recommendations soon.
Thank you,Bob
Bump!
Robert Hook
Yongan.Fu
Mangesh.Shelar
Thanks,
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
I don't think cell APIs in .NET work well. It seems to be a problem for a long time. I am still recommend Chinese developers to use Interop(VBA/COM) API to operate cells when they want to use C#.
Hi Yongan,
Yongan.Fu said:I don't think cell APIs in .NET work well. It seems to be a problem for a long time.
Can it be reported to core / API developers to fix it? Or, at least, to add some note to NET documentation?
Yongan.Fu said:I am still recommend Chinese developers to use Interop(VBA/COM) API to operate cells when they want to use C#.
I agree, it is solution, but it's just weird ... there is extensive new NET API, offering plenty of functionality, and it does not support cell (which is one from the core "building blocks" in many applications) correctly?
I prefer, when similar situation happens, to use C++/CLI, especially when more complex functionality is required. But it's true C++/CLI knowledge is not common.