.Net - How to insert a Field into a MText?

To create a field in the text, I used code like this:

        MText mt = new MText();
        mt.Contents = “%<\\AcObjProp Object(%<\\_ObjId 1438088896>%).Layer>%”;

This works great in AutoCAD. But in BricsCAD 18 this method does not work. In the drawing not a field appears, but just text disappear symbols “\A”. In my example it will be like this:

  %<cObjProp Object(%<\_ObjId 1438088896>%).Layer>%

Such an expression is certainly not perceived by the program as a field.
I tried to assign a field like this:

          MText mt = new MText();
          if (text.Contains("%<\\"))
          {
            Field f = new Field(text);
            f.Evaluate();
            mt.SetField(f);
            tr.AddNewlyCreatedDBObject(f, true);
          }
          else
            mt.Contents = text;

And yet like this

          MText mt = new MText();
          if (text.Contains("%<\\"))
          {
            Field f = new Field(text);
            f.EvaluationOption = FieldEvaluationOptions.Automatic;
            f.Evaluate((int)(FieldEvaluationOptions.Automatic), db);
            mt.SetField(f);
            tr.AddNewlyCreatedDBObject(f, true);
          }
          else
            mt.Contents = text;

In both cases, a non-working field is obtained. If the user tries to edit such a field, it disappears. If I use the debugger and check the status of the field after the evaluation, I always get InvalidContext.
Exactly the same problems occur when I insert field in a table.
Help please make BricsCAD work with fields.

Comments

  • Support ++

    I have the same problem in Lisp.

    Using this code
    http://www.lee-mac.com/areastofield.html

    works fine in AutoCAD for single and multiple selection.

    In Bricscad it works only with one single object, with multiple elements there is also the "\A" disappearing.

  • ...And the problem successfully migrated to V19 beta

  • Its_Alive
    edited December 2018

    Hi, Give this a whirl

            static private bool Func(Document doc, Database db, Editor ed)
            {
                try
                {
                    ObjectId id = ed.GetEntity("Get it:").ObjectId;
                    string fc = string.Format("\\AcObjProp Object(%<\\_ObjId {0}>%).Layer", id);
                    ObjectId mtId;
                    using (MText mt = new MText())
                    {
                        mt.SetDatabaseDefaults(db);
                        using (var ms = db.CurrentSpaceId.Open(OpenMode.ForWrite) as BlockTableRecord)
                            mtId = ms.AppendEntity(mt);
                    }
    
                    using (MText mt = mtId.Open(OpenMode.ForWrite) as MText)
                    {
                        using (Field pfield = new Field("The layer is: %<\\_FldIdx 0>%", true))
                        {
                            using (Field cfield = new Field(fc,false))
                            {
                                db.AddDBObject(pfield);
                                db.AddDBObject(cfield);
                                FieldCodeWithChildren fcwc = pfield.GetFieldCodeWithChildren();
                                fcwc.Add(0, cfield);
                                pfield.SetFieldCodeWithChildren(FieldCodeFlags.PreserveFields, fcwc);
                                pfield.EvaluationOption = FieldEvaluationOptions.Automatic;
                                cfield.EvaluationOption = FieldEvaluationOptions.Automatic;
                                mt.SetField("TEXT", pfield);
                                cfield.Evaluate((int)FieldEvaluationOptions.OnDemand, db);
                                pfield.Evaluate((int)FieldEvaluationOptions.OnDemand, db);
                            }
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    ed.WriteMessage("\nMessage-{0}\nStack Trace-{1}", ex.Message, ex.StackTrace);
                    return false;
                }
                return true;
            }
    
  • So very difficult way around.... I can not even think how to screw itto my code. ...Especially when I need to fill the table with fields.
    But maybe someone is useful. Thank.

  • @avc said:
    So very difficult way around.... I can not even think how to screw itto my code. ...Especially when I need to fill the table with fields.
    But maybe someone is useful. Thank.

    Well you did say mtext ;-)

    yeah, a little more verbose, but not impossible .. so here's a version for tables

           static private bool Func(Document doc, Database db, Editor ed)
            {
                try
                {
                    ObjectId id = ed.GetEntity("\nSelect entity:").ObjectId;
                    ObjectId tid = ed.GetEntity("\nSelect Table:").ObjectId;
                    if (!tid.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(Table))))
                        return false;
                    Point3d hitPoint = ed.GetPoint("\nPoint point in Cell").Value;
                    string fc = string.Format("\\AcObjProp Object(%<\\_ObjId {0}>%).Layer", id);
                    using (Table table = tid.Open(OpenMode.ForWrite) as Table)
                    {
                        TableHitTestInfo info = table.HitTest(hitPoint, Vector3d.ZAxis);
                        if (info.Type == TableHitTestType.Cell && info.Row >=0 && info.Column >= 0)
                        {
                            using (Field pfield = new Field("The layer is: %<\\_FldIdx 0>%", true))
                            {
                                using (Field cfield = new Field(fc, false))
                                {
                                    ObjectId fid = db.AddDBObject(pfield);
                                    db.AddDBObject(cfield);
                                    FieldCodeWithChildren fcwc = pfield.GetFieldCodeWithChildren();
                                    fcwc.Add(0, cfield);
                                    pfield.SetFieldCodeWithChildren(FieldCodeFlags.PreserveFields, fcwc);
                                    pfield.EvaluationOption = FieldEvaluationOptions.Automatic;
                                    cfield.EvaluationOption = FieldEvaluationOptions.Automatic;
                                    if (table.GetNumberOfContents(info.Row, info.Column) == 0)
                                        table.CreateContent(info.Row, info.Column, 0);
                                    table.SetFieldId(info.Row, info.Column, fid);
                                    cfield.Evaluate((int)FieldEvaluationOptions.OnDemand, db);
                                    pfield.Evaluate((int)FieldEvaluationOptions.OnDemand, db);
                                }
                            }
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    ed.WriteMessage("\nMessage-{0}\nStack Trace-{1}", ex.Message, ex.StackTrace);
                    return false;
                }
                return true;
            }
    
  • I understood the meaning. Thank you Daniel!

  • hello, thank you very much for this productive sharing. but the part I couldn't solve was the fields made using the formula. that is, I can connect the length of a line with this method, but I could not be successful in a field that I wanted to create by multiplying the length of the line by 100. Does anyone have any knowledge about this?