Through the Interface: Changing the layer of an entity in an AutoCAD block using .NET

May 2015

Sun Mon Tue Wed Thu Fri Sat
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30


« API wishlist surveys for Max and Maya | Main | Creating an AutoCAD MText object containing different colours using .NET »

June 04, 2010

Changing the layer of an entity in an AutoCAD block using .NET

After seeing Shaan list the results of the latest AUGI wishlist, I started thinking about which of the items would be worth covering either on this blog or via a Plugin of the Month. The second item on the list, “Automatically Differentiate Manually Edited Dimensions”, has (hopefully) been addressed by Dimension Patrol, this month’s Plugin of the Month, so that’s a good start, anyway.

The first item, “Change Objects in a Block to a new Layer”, seemed as good a good place to start as anywhere.

Here’s some C# code that builds upon a technique for selecting/highlighting nested entities shown in a previous post to actually modify their layers.

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.Runtime;


namespace NestedObjectModification


  public class Commands



    static public void ChangeNestedLayer()


      Document doc =


      Database db = doc.Database;

      Editor ed = doc.Editor;


      // Collection of our selected entities


      ObjectIdCollection ids = new ObjectIdCollection();


      // The results object for our nested selection

      // (will be reused)


      PromptNestedEntityResult rs;


      // Start a transaction... will initially be used

      // to highlight the selected entities and then to

      // modify their layer


      Transaction tr =


      using (tr)


        // Loop until cancelled or completed




          rs = ed.GetNestedEntity("\nSelect nested entity: ");


          if (rs.Status == PromptStatus.OK)




            HighlightSubEntity(doc, rs);



        while (rs.Status == PromptStatus.OK);


        if (ids.Count > 0)


          // Get the name of our destination later


          PromptResult pr =

            ed.GetString("\nNew layer for these objects: ");

          if (pr.Status == PromptStatus.OK)


            // Check that the layer exists


            string newLay = pr.StringResult;


            LayerTable lt =

              tr.GetObject(db.LayerTableId, OpenMode.ForRead)

                as LayerTable;


            if (lt.Has(newLay))


              // If so, set the layer name to be the one chosen

              // on each of the selected entitires


              for (int i = 0; i < ids.Count; i++)


                Entity ent =

                  tr.GetObject(ids[i], OpenMode.ForWrite) as Entity;

                if (ent != null)


                  ent.Layer = newLay;







                "\nLayer not found in current drawing."







        // Regen clears highlighting and reflects the new layer






    private static void HighlightSubEntity(

      Document doc, PromptNestedEntityResult rs



      // Extract relevant information from the prompt object


      ObjectId selId = rs.ObjectId;

      ObjectId[] objIds = rs.GetContainers();

      int len = objIds.Length;


      // Reverse the "containers" list


      ObjectId[] revIds = new ObjectId[len + 1];

      for (int i = 0; i < len; i++)


        ObjectId id =

          (ObjectId)objIds.GetValue(len - i - 1);

        revIds.SetValue(id, i);



      // Now add the selected entity to the end


      revIds.SetValue(selId, len);


      // Retrieve the sub-entity path for this entity


      SubentityId subEnt =

        new SubentityId(SubentityType.Null, 0);

      FullSubentityPath path = new FullSubentityPath(revIds, subEnt);


      // Open the outermost container, relying on the open

      // transaction...


      ObjectId id2 = (ObjectId)revIds.GetValue(0);

      Entity ent = id2.GetObject(OpenMode.ForRead) as Entity;


      // ... and highlight the nested entity


      if (ent != null)

        ent.Highlight(path, false);




I’d really categorise this as a first attempt, as there are some minor quirks that I’m not fully happy with. For instance, when you cancel the initial selection loop using the escape key, the application still proceeds to ask the user for the destination layer. Also, the current implementation doesn’t limit modification of objects inside Xrefs, which clearly won’t result in an actual drawing change, as the nested entity is not being modified via a long transaction.

But as it stands the application should be complete enough to prove useful and should certainly allow people to provide feedback on whether this should be developed further into a future Plugin of the Month.

After building and NETLOADing the application, you can use the CNL command to change the layer of the nested entities you select. Here are some sample blocks that ship with AutoCAD, followed by the highlighting during the selection and finally the updated contents:

Some standard blocks Selected block contents Modified block contents

blog comments powered by Disqus


10 Random Posts