[Connect Update 16 .NET] Updating element inside of cell

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.

Parents
  • 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.



  • Thanks, I guess if i use COM api, I don't really need to replace the element, you can simply iterate the subelements, update text and then rewrite them. I guess that would be my last option, but then i'm back to square one and limited text processing that COM has, I was just getting used to the NET api there...              

    If I choose c++ api, is there an example how to have a c++ method within your .NET project? Do I just add a cpp file and more references? this would be all new to me.

    This is kind of depressing, I'm told to use NET api because its the future & COM api is old and doesn't support new features and at the same time NET api is not fully baked either and poorly documented. 

  • Is there an example how to have a C++ method within your .NET project?

    Microsoft calls that either P/Invoke, if you want to call a handful of functions, or C++/CLI.  You probably don't want to write much of that code, because you have to use unorthodox C++ syntax.

    You can also go in the opposite direction.  Here's an example of a C++ client that uses a .NET DLL.

    I'm told to use NET api because its the future & COM api is old

    C++ is pretty good.  It falls down when designing the User Interface, because standard C++ doesn't have such a thing. 

     
    Regards, Jon Summers
    LA Solutions

  • Thanks Jon, yea the C++ with .NET dll would definitely NOT be my approach, I am as green as they come in c++. and UI is important.

    I think I can figure out the code part of the C++ based on all the examples, my main concern is that how do I add that file into my project? Do i need to reference? or just include the file?

Reply Children
  • HI Viktor,

    but then i'm back to square one and limited text processing that COM has, I was just getting used to the NET api there...              

    Unfortunately you hit one from several issues, still existing in NET API. There are not many of them right now, the most critical are placing cell from cell ibrary and the discussed cell content editing. Unfortunately, Bentley are not able to fix it (for unknown reason), even when requested many times for last several years.

    If I choose c++ api, is there an example how to have a c++ method within your .NET project?

    It is standard NET Framework (not MicroStation) feature, so it's possible to find plenty of tutorials and examples on Internet. As Jon wrote, there are in general two ways:

    • P/Invoke is NET feature from version 1.0, because Microsoft was aware it is not possilbe to create NET as isolated world and many applications must interact with existing native code in some way.
    • The second option is C++/CLI, which is used extensively also in MicroStation (I guess a substantial part of NET API is built using this tool). In fact it is an extension of P/Invoke, because this language allows to mix native and managed code in one project, and data type marshalling is done autoamtically at background.
    Do I just add a cpp file and more references? this would be all new to me.

    It depends what way you choose:

    • P/Invoke is quite low level feature, so you "import" dll file and access functions, published in native dll. You are responsible for data marhsalling (the way, how native/managed data transformation is done).
    • C++/CLI creates standard (but not pure) NET assembly, that can be referenced in NET project in a standard way.
    This is kind of depressing, I'm told to use NET api because its the future & COM api is old and doesn't support new features

    Generally, it's true. NET API covers the most of native API (but it was never promissed it will be equal), whereas Interop (built on top of COM API) represents only a fraction of functions. But, and it was discussed many times, there are some (only a few in my opinion) situations, when COM is better.

    But, as far as I remember, the clear message from Bentley alwas was "when you need complete functionality, C++ is the only recommended choice, whereas NET is better to build GUI". In my opinion it is normal that different tools, languages and APIs are used in one project, to ensure the best tool is used to solve particular requirement.

    and at the same time NET api is not fully baked either and poorly documented. 

    I must say I use typically C++ documentation + dnSpy or NET Reflector, not NET one, beause as you wrote, it is not very usefull (but, exceptions exist, and some features are described in the great detail in NET doc ;-)

    Regards,

      Jan