Many AutoCAD commands that work on sets of entities support two styles of working: verb-noun or noun-verb. This basically means that if the user has pre-selected a set of entities (the "noun") and then launch the command (the "verb") then the command will not need to request the user select them.
This is enabled using something called the pickfirst or implied selection set inside AutoCAD. To take advantage of this feature inside your commands the first thing to do is to use a special command-flag called "UsePickSet": this tells the AutoCAD editor not to clear the pickfirst set when the command is invoked. Next the command implementation will use the SelectImplied() method on the editor object to retrieve the pickfirst set, should one be available. At this stage it's also good practice to clear the pickfirst set with SetImpliedSelection().
The following C# sample shows a few extras, such as how to fall back on asking the user to select the objects if there isn't a pickfirst set. As for what we do with the selected entities... in this simple example each entity is opened for read and has its list() method called to dump out its contents to the command-line (just as the LIST command does). You could, of course, do something much more interesting with the object at this point (I'll try to show more examples of getting specific entity properties in a later post).
Here's the code:
using Autodesk.AutoCAD;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
namespace SelectionTest
{
public class PickfirstTestCmds
{
// Must have UsePickSet specified
[CommandMethod("PFT", CommandFlags.UsePickSet |
CommandFlags.Redraw |
CommandFlags.Modal)
]
static public void PickFirstTest()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
try
{
PromptSelectionResult selectionRes =
ed.SelectImplied();
// If there's no pickfirst set available...
if (selectionRes.Status == PromptStatus.Error)
{
// ... ask the user to select entities
PromptSelectionOptions selectionOpts =
new PromptSelectionOptions();
selectionOpts.MessageForAdding =
"\nSelect objects to list: ";
selectionRes =
ed.GetSelection(selectionOpts);
}
else
{
// If there was a pickfirst set, clear it
ed.SetImpliedSelection(new ObjectId[0]);
}
// If the user has not cancelled...
if (selectionRes.Status == PromptStatus.OK)
{
// ... take the selected objects one by one
Transaction tr =
doc.TransactionManager.StartTransaction();
try
{
ObjectId[] objIds = selectionRes.Value.GetObjectIds();
foreach (ObjectId objId in objIds)
{
Entity ent =
(Entity)tr.GetObject(objId, OpenMode.ForRead);
// In this simple case, just dump their properties
// to the command-line using list
ent.List();
ent.Dispose();
}
// Although no changes were made, use Commit()
// as this is much quicker than rolling back
tr.Commit();
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
ed.WriteMessage(ex.Message);
tr.Abort();
}
}
}
catch(Autodesk.AutoCAD.Runtime.Exception ex)
{
ed.WriteMessage(ex.Message);
}
}
}
}