Highlighting a nested AutoCAD block using .NET

OK, I have to admit I feel a bit cheeky making a separate post out of this one, but then I did promise our friends at TheSwamp that I'd post this additional code, once more provided by Sreekar Devatha in response to an ADN support request.

The code is basically the same as that in my last post. The only change is that after we reverse the list of containers we don't go and add in the selected entity. Which means that when we get our path it stops at the container of the selected entity, not the entity itself.

I've extended the code to define two commands - HLNESTEDENT and HLNESTEDBLK - using the same internal function, InternalHighlightNested(). Check the use of the isEntity flag in the code, to see how it differs for the two commands.

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.Runtime;

namespace MySelectionApp

{

  public class MySelectionCmds

  {

    [CommandMethod("HLNESTEDBLK")]

    static public void HighlightNestedBlock()

    {

      InternalHighlightNested(false);

    }

    [CommandMethod("HLNESTEDENT")]

    static public void HighlightNestedEntity()

    {

      InternalHighlightNested(true);

    }

    static private void InternalHighlightNested(bool isEntity)

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Editor ed = doc.Editor;

      PromptNestedEntityResult rs =

        ed.GetNestedEntity(

          "\nSelect nested " +

          (isEntity ? "entity" : "block") +

          ": "

        );

      if (rs.Status == PromptStatus.OK)

      {

        ObjectId[] objIds = rs.GetContainers();

        ObjectId ensel = rs.ObjectId;

        int len = objIds.Length;

        // Reverse the "containers" list

        ObjectId[] revIds;

        if (isEntity)

          revIds = new ObjectId[len + 1];

        else

          revIds = new ObjectId[len];

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

        {

          ObjectId id =

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

          revIds.SetValue(id, i);

        }

        // Add the selected entity to the end, if needed

        if (isEntity)

          revIds.SetValue(ensel, len);

        // Check to make sure a single entity has not been

        // picked (in the case of a block)

        if (revIds.Length > 0)

        {

          // Retrieve the sub-entity path for this entity

          SubentityId subEnt =

            new SubentityId(SubentityType.Null, 0);

          FullSubentityPath path =

            new FullSubentityPath(revIds, subEnt);

          Transaction tr =

            doc.TransactionManager.StartTransaction();

          using (tr)

          {

            // Open the outermost container...

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

            Entity ent =

              (Entity)tr.GetObject(id, OpenMode.ForRead);

            // ... and highlight the nested entity

            ent.Highlight(path, false);

            tr.Commit();

          }

        }

      }

    }

  }

}

3 responses to “Highlighting a nested AutoCAD block using .NET”

  1. Hi Kean:
    I found this (1 at Fernando Malard's blog. is it possible in .NET? Would you mind give some sample code about it?

    Merry Christmas

    Wes

  2. Hi Wes,

    I haven't tried it myself from .NET, but given the way this used to work from VB6/VBA, I'd suggest trying this:

    System.Windows.Forms.Application.DoEvents();

    Happy New Year!

    Kean

  3. Christian Baker Avatar
    Christian Baker

    I am using an mleader with a block as the data... how can I read/write the attributes in the subentity block in the mleader?

Leave a Reply to Christian Baker Cancel reply

Your email address will not be published. Required fields are marked *