I've gone through all the threads I could find regarding ReplaceInModel method when it applies to elements within a cell and so far no one has provided any direction. In the code below:
TextElement origElem = (TextElement)Element.GetFromElementRef(elem.GetNativeElementRef()); TextElement t = (TextElement)elem; TextBlock tb = t.GetTextPart(id); tb.Remove(tb.CreateStartCaret(), tb.CreateEndCaret()); tb.InsertText(tb.CreateStartCaret(), newValue); if (TextReplaceStatus.Success == t.ReplaceTextPart(id, tb)) { t.ReplaceInModel(origElem); }
If the TextElement is within CellElement, the t.ReplaceInModel will crash microstation. Do I need to somehow update the CellElement? And if its a multi-level Cell, like Cell within a Cell, do I need to update the top level Cell?
Thanks.
Sure. A lot of threads report .NET API has a bug for modifying sub elements in cell. I can replicate this as well.
Two workarounds: 1.Use Interop API as below:
using BIM = Bentley.Interop.MicroStationDGN; using BMI = Bentley.MstnPlatformNET.InteropServices; public static void ReplaceInCell(string unparsed) { BIM.Application app = BMI.Utilities.ComApp; BIM.CellElement myCell = app.ActiveModelReference.GetElementByID64(583L) as BIM.CellElement; myCell.ResetElementEnumeration(); int nestDepth = 0; while(myCell.MoveToNextElement(true, ref nestDepth)) { BIM.Element tempEl = myCell.CopyCurrentElement(); if (tempEl.IsTextElement()) { BIM.TextElement oldTextEl = tempEl.AsTextElement(); BIM.Point3d org = oldTextEl.get_Origin(); BIM.Matrix3d matrix = oldTextEl.get_Rotation(); BIM.TextElement newTextEl = app.CreateTextElement1(oldTextEl, "ReplaceText", ref org, ref matrix); myCell.ReplaceCurrentElement(newTextEl); } } myCell.Rewrite(); }
2. Use C++ API.
what is the c++ version of modifiying elements within cell?
amender carapace said:what is the c++ version of modifiying elements within cell?
C++ version is defined by used MicroStation version. The last several versions used C++ toolset, delivered with Visual Studio 2017, plus the latest Update 16.2 allows to use also Visual Studio 2019 (but I guess the same toolset is used there).
Regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
do you have a specific example or code or mdl function?
amender carapace said:do you have a specific example or code or mdl function?
Do we well known old MDL-C concept MSElementDescr? A cell can be read as an MSElementDescr, you can iterate every element in it and can replace any element by using mdlElmdscr_replaceElement.
Hi Yongan.Fu , do you know if there were any updates to the .NET API in this regard? Updating elements inside of cell?
No. .NET API still has problems for this.
Answer Verified By: Viktor_Kulik
is it possible to recreate a cell from scratch in .net, basically clone every element inside it and then replace the original cell with the new cell that has slightly modified elements?
ChatGPT thinks this should be very easy haha... initially it provided a method to create a new cell elelement and a new text element. So I clarified.
Hi Yongan,
Yongan.Fu said:No. .NET API still has problems for this.
thanks for the confirmation.
How it can be prioritized? Two main issues in NET API: to place cell from a cell library and to edit a cell content are reported for years from CE release date, but there is still no fix available.
Viktor_Kulik said:basically clone every element inside it and then replace the original cell with the new cell that has slightly modified elements?
I think, when discussed generally, the situation is not simple: There can be data attached both in (user data linkages) and on element (XAttributes etc.), so to create identical copy can be complex task.
When it is clear that the cell is "only graphics", the cloning would be fine. But the question is whether is is not simpler to use Interop or to write own wrapper and to move the functionality to native code.
With regards,
Jan Šlegr said:NET API: to place cell from a cell library
Almost all.NET APIs are encapsulated from C++ APIs. Currently there is no a C++ CreateCellFromCellLib function under the NormalCellHeader nor SharedCellHeader. So there is no a corresponding .NET API for it.
In C++, the workaround is calling old C functions.
In C#, the workaround is calling Interop/COM functions.
Bugs/Enhancements(new name is PBIs) had filed for a long time.