问题
I have some trouble to select the targeted acadObject
. I get the input via selectionset.SelectonScreen
method.
Here i can get more number of object from modelspace based on my filter condition.But i need only one object from the user.
Here i mentioned my code below:
AcadSelectionSet selset= null;
selset=currDoc.selectionset.add("Selset");
short[] ftype=new short[1];
object[] fdata=new object[1];
ftype[0]=2;//for select the blockreference
fdata[0]=blkname;
selset.selectOnScreen ftype,fdata; // Here i can select any no. of blocks according to filter value but i need only one block reference.
Please help me to solve this problem.
回答1:
That's possible using other Autocad .NET libraries (instead of Interop library). But fortunately, one does not exclude the other.
You will need to reference the libraries containing the following namespaces:
using Autodesk.Autocad.ApplicationServices
using Autodesk.Autocad.EditorInput
using Autodesk.Autocad.DatabaseServices
(you get those downloading the Object Arx libraries for free from Autodesk):
You will need to access the Editor
from an autocad Document
.
By the code you've shown, you're probably working with AcadDocument
documents.
So, to transform an AcadDocument
into a Document
, do this:
//These are extension methods and must be in a static class
//Will only work if Doc is saved at least once (has full name) - if document is new, the name will be
public static Document GetAsAppServicesDoc(this IAcadDocument Doc)
{
return Application.DocumentManager.OfType<Document>().First(D => D.Name == Doc.FullOrNewName());
}
public static string FullOrNewName(this IAcadDocument Doc)
{
if (Doc.FullName == "")
return Doc.Name;
else
return Doc.FullName;
}
Once you've got a Document
, get the Editor
, and the GetSelection(Options, Filter)
The Options contains a property SingleOnly
and a SinglePickInSpace
. Setting that to true
does what you want. (Try both to see wich works better)
//Seleciton options, with single selection
PromptSelectionOptions Options = new PromptSelectionOptions();
Options.SingleOnly = true;
Options.SinglePickInSpace = true;
//This is the filter for blockreferences
SelectionFilter Filter = new SelectionFilter(new TypedValue[] { new TypedValue(0, "INSERT") });
//calls the user selection
PromptSelectionResult Selection = Document.Editor.GetSelection(Options, Filter);
if (Selection.Status == PromptStatus.OK)
{
using (Transaction Trans = Document.Database.TransactionManager.StartTransaction())
{
//This line returns the selected items
AcadBlockReference SelectedRef = (AcadBlockReference)(Trans.GetObject(Selection.Value.OfType<SelectedObject>().First().ObjectId, OpenMode.ForRead).AcadObject);
}
}
回答2:
this is a direct quote from autocad developer help
http://docs.autodesk.com/ACD/2013/ENU/index.html?url=files/GUID-CBECEDCF-3B4E-4DF3-99A0-47103D10DADD.htm,topicNumber=d30e724932
There is tons of documentation the AutoCAD .NET API.
you will need to have
[assembly: CommandClass(typeof(namespace.class))]
above your namespace if you want to be able to invoke this command from the command line after you NetLoad
the .dll, if it is a classLibrary.
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
[CommandMethod("SelectObjectsOnscreen")]
public static void SelectObjectsOnscreen()
{
// Get the current document and database
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
// Start a transaction
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
// Request for objects to be selected in the drawing area
PromptSelectionResult acSSPrompt = acDoc.Editor.GetSelection();
// If the prompt status is OK, objects were selected
if (acSSPrompt.Status == PromptStatus.OK)
{
SelectionSet acSSet = acSSPrompt.Value;
// Step through the objects in the selection set
foreach (SelectedObject acSSObj in acSSet)
{
// Check to make sure a valid SelectedObject object was returned
if (acSSObj != null)
{
// Open the selected object for write
Entity acEnt = acTrans.GetObject(acSSObj.ObjectId,
OpenMode.ForWrite) as Entity;
if (acEnt != null)
{
// Change the object's color to Green
acEnt.ColorIndex = 3;
}
}
}
// Save the new object to the database
acTrans.Commit();
}
// Dispose of the transaction
}
}
来源:https://stackoverflow.com/questions/17272173/how-to-get-only-one-acadobject-by-selection-set