C# 如何通过选择集仅获取一个acadobject

C# 如何通过选择集仅获取一个acadobject,c#,autocad,C#,Autocad,我在选择目标acadObject时遇到一些问题。我通过selectionset.SelectonScreen方法获取输入 在这里,我可以根据过滤条件从模型空间获得更多的对象,但我只需要用户提供一个对象 这里我提到了我的代码如下: AcadSelectionSet selset= null; selset=currDoc.selectionset.add("Selset"); short[] ftype=new short[1]; object[] fdata=new object[1]; fty

我在选择目标
acadObject
时遇到一些问题。我通过
selectionset.SelectonScreen
方法获取输入

在这里,我可以根据过滤条件从模型空间获得更多的对象,但我只需要用户提供一个对象

这里我提到了我的代码如下:

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.

请帮助我解决此问题。

可以使用其他Autocad.NET库(而不是互操作库)。但幸运的是,一方并不排斥另一方

您需要引用包含以下命名空间的库:

using Autodesk.Autocad.ApplicationServices
using Autodesk.Autocad.EditorInput
using Autodesk.Autocad.DatabaseServices
(您可以从Autodesk免费下载对象Arx库):

您需要从autocad
文档
访问
编辑器
。 根据您显示的代码,您可能正在使用
AcadDocument
文档。 因此,要将
文档
转换为
文档
,请执行以下操作:

//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());
    }

获得
文档
后,获取
编辑器
,以及
GetSelection(选项,过滤器)

这些选项包含一个属性
SingleOnly
和一个
SinglePickInSpace
。将其设置为
true
可以满足您的需要。(尝试两种方法,以确保wich效果更好)

//选择选项,具有单个选择
PromptSelectionOptions=新建PromptSelectionOptions();
Options.SingleOnly=true;
Options.SinglePickInSpace=true;
//这是块引用的过滤器
SelectionFilter=new SelectionFilter(new-TypedValue[]{new-TypedValue(0,“插入”)});
//调用用户选择
PromptSelectionResult Selection=Document.Editor.GetSelection(选项,过滤器);
if(Selection.Status==PromptStatus.OK)
{
使用(Transaction Trans=Document.Database.TransactionManager.StartTransaction())
{
//此行返回所选项目
AcadBlockReference SelectedRef=(AcadBlockReference)(Trans.GetObject(Selection.Value.OfType().First().ObjectId,OpenMode.ForRead).AcadObject);
}
}

这是autocad开发者帮助中的直接引用

AutoCAD.NET API中有大量的文档

你需要有

[程序集:CommandClass(typeof(namespace.class))]

如果您希望能够在.dll(如果它是类库)之后从命令行调用此命令,请在命名空间上方

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
  }
}

一个简单的方法是,如果计数>1,则显示消息,然后再次选择。这不是一个干净的解决方案,但我找到了这个解决方案。我讨厌使用那些Arx库,因为这些事务和复杂的过滤器,但有时它们工作得更好。您的解决方案可能是OP的最佳解决方案,但是您的术语不正确。“ARX”是严格的本地C++。托管API的正确术语是“AutoCAD .NETAPI”,对于原生C++ API,它是“ObjectARX”。好的……直到现在我才知道它的区别。Autodesk在这些问题上的文档记录非常糟糕。互操作程序集是
Autodesk.Autocad.interop.dll
Autodesk.Autocad.Interop.Common.dll这些是绝对相互排斥的。进程内程序集是
AcDbMgd.dll
acmgd.dll
。您好,@BKSpurgeon,我已经多年没有使用Autocad了,但我假设它可以防止用户在希望他们只拾取一个图元时一次拾取大量图元。
//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);
    }
}
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
  }
}