Adding to the AutoCAD pickfirst set with .NET

Back in a much earlier post we looked at some code to access the pickfirst selection set.

I thought I'd now take a look at the more specific case of defining a command that adds entities into the current pickfirst selection set.

Here's some C# code I used to do this, with comments describing its behaviour. The most interesting point is that once we get the contents of the existing pickfirst set we then clear it and rehighlight the entities manually, to give the user a graphical clue of the previous contents.

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

namespace SelectionTest

{

  public class PickfirstTestCmds

  {

    [CommandMethod("PFA", CommandFlags.Modal |

                          CommandFlags.UsePickSet |

                          CommandFlags.Redraw)

    ]

    public void AddToPickfirstSet()

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Editor ed = doc.Editor;

      // First let's get the initial pickfirst set

      PromptSelectionResult sr =

        ed.SelectImplied();

      // Create a collection containing the initial set

      //  (could have used an array, but a collection is

      //  easier in dynamic situations, such as this)

      ObjectIdCollection objs;

      if (sr.Status == PromptStatus.OK)

        objs =

          new ObjectIdCollection(

          sr.Value.GetObjectIds()

        );

      else

        objs = new ObjectIdCollection();

      // Clear the pickfirst set...

      ed.SetImpliedSelection(new ObjectId[0]);

      // ...but highlight the objects

      if (objs.Count > 0)

        HighlightEntities(objs);

      // No ask the user to select objects

      sr = ed.GetSelection();

      if (sr.Status == PromptStatus.OK)

      {

        // Add them all to the collection

        foreach (ObjectId obj in sr.Value.GetObjectIds())

        {

          objs.Add(obj);

        }

        // Dump the collection to an array

        ObjectId[] ids = new ObjectId[objs.Count];

        objs.CopyTo(ids, 0);

        // And finally set the pickfirst set

        ed.SetImpliedSelection(ids);

      }

    }

    // Highlight the entities by opening them one by one

    private void HighlightEntities(ObjectIdCollection objIds)

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Transaction tr =

        doc.TransactionManager.StartTransaction();

      using (tr)

      {

        foreach (ObjectId objId in objIds)

        {

          Entity ent =

            tr.GetObject(objId, OpenMode.ForRead)

            as Entity;

          if (ent != null)

            ent.Highlight();

        }

      }

    }

  }

}

9 responses to “Adding to the AutoCAD pickfirst set with .NET”

  1. Hi,
    I have been reading through these tutorials to find an equvilant way to to access function avaibable in VBA Thisdrawing, particulary: SelectionChanged, ObjectAdded and Activate.
    I have noticed in the examples similar functions can be accessed using .Net applications, but first the CommandMethod method must be run. Is it possible to have the functions waiting for autoCAD methods without calling CommandMethod?

    Regards

    Chris

  2. Hi Chris,

    Absolutely. Check out this post, which shows how to implement code that is executed when your module is loaded.

    Regards,

    Kean

  3. Hi Kean,

    I'm looking for a possibility to "preselect" some entities in some way, then call GetSelection to add other entities (filtered), where the preselected entities are already part of the new selection set and highlighted on screen, and can be deselected by the user. Do you know if this is possible? I don't need a pan ready solution, just a hint where to start.

    TIA - Martin

    1. Hi Martin,

      That's an interesting question. You could certainly pick up the pickfirst selection set in your command. What would be interesting to see if that already sets the "previous" selection set for you to use in a new selection prompt (a bit of a kludge, admittedly, but I'd tried sending the "_previous" keyword to the prompt, to see what happened).

      There may be another way to do this, but it'll take some research. If you haven't had any luck in a few days, ping me back. 🙂

      Regards,

      Kean

      1. Hi Kean

        Thank you for your quick reply.

        I just wanted to point future readers which might come here because of their search engine terms to the solution I found with the help of Autodesk forum. Hope this is ok for you. forums.autodesk.com/

        Regards,
        Martin

        1. Hi Martin,

          Great! 🙂

          Thanks for letting us know,

          Kean

  4. Hi Kean,

    I have found that once you have selected some entities and then use AutoCAD copy or mirror commands, the order in which the objects are appended to the db seems to be random, ie it does not correspond to the selection order. I have a requirement that entities of a particular type be cloned before others (because there is a dependency) when several objects are selected for copying. Is this possible?

    1. Hi Paul,

      You can manage cloning dependencies in your app... but that's a bigger topic (and unrelated to this post). Please post your question to the relevant Autodesk discussion forum - someone there should be able to provide some insights.

      You might start by looking at ObjectOverrule.DeepClone() (I assume that's what you'll need if you're not talking about custom objects/entities).

      Regards,

      Kean

      1. Thanks Kean I'll look into it.

Leave a Reply to Martin Müller Cancel reply

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