AutoCAD Managed .NET API 允许您使用使用. NET 4.0 引入的动态语言运行时 (DLR)。

使用 DLR 可以直接访问对象, 而无需:

在使用 DLR 时获得对象的 ObjectId 后, 可以直接访问对象的属性和方法。获得 ObjectId 后, 可以将 ObjectId 分配给数据类型的变量:

获取 ObjectId 因对象保存到数据库的方式而异。对于存储在表或字典中的对象, 可以通过以下方式访问其 ObjectId:

下面的示例代码显示了用于访问存储在与 DLR 的表或字典中的对象的两个选项:

// Item method
dynamic acCurDb = HostApplicationServices.WorkingDatabase;
dynamic acMSpace = acCurDb.BlockTableId.Item(BlockTableRecord.ModelSpace);

// Reference an element directly from a collection
dynamic acCurDb = HostApplicationServices.WorkingDatabase;
dynamic acBlkTbl = acCurDb.BlockTableId;
dynamic acMSpace = acBlkTbl[BlockTableRecord.ModelSpace];

重要提示: 在使用 DLR 和 C# 时, 您需要引用 Microsoft.CSharp 库。

使用 GetEnumerator 方法

在将 GetEnumerator 方法与 DLR 一起使用时, 需要在使用完枚举器对象后显式释放该对象。下面的示例演示如何在完成枚举器时对其进行处置。

dynamic acCurDb = HostApplicationServices.WorkingDatabase;
var acLtypeTbl = acCurDb.LinetypeTableId;
var acTblEnum = acLtypeTbl.GetEnumerator();
...
acTblEnum.Dispose();

使用 LINQ 查询

您可以利用 LINQ 查询在使用 DLR 的图形中查询表或字典的内容。下面的示例演示如何使用 LINQ 查询来查询哪些图层在当前图形中具有分配给它们的某些状态。

[CommandMethod("LINQ")]
public static void LINQExample()
{
    dynamic db = HostApplicationServices.WorkingDatabase;
    dynamic doc = Application.DocumentManager.MdiActiveDocument;

    var layers = db.LayerTableId;
    for (int i = 0; i < 2; i++)
    {
        var newrec = layers.Add(new LayerTableRecord());
        newrec.Name = "Layer" + i.ToString();
        if (i == 0)
            newrec.IsFrozen = true;
        if (i == 1)
            newrec.IsOff = true;
    }

    var OffLayers = from l in (IEnumerable<dynamic>)layers
                    where l.IsOff
                    select l;

    doc.Editor.WriteMessage("\nLayers Turned Off:");

    foreach (dynamic rec in OffLayers)
        doc.Editor.WriteMessage("\n - " + rec.Name);

    var frozenOrOffNames = from l in (IEnumerable<dynamic>)layers
                            where l.IsFrozen == true || l.IsOff == true
                            select l;

    doc.Editor.WriteMessage("\nLayers Frozen or Turned Off:");

    foreach (dynamic rec in frozenOrOffNames)
        doc.Editor.WriteMessage("\n - " + rec.Name);
}

示例代码

此页上的示例代码使用以下名称空间:

Autodesk.AutoCAD.Runtime
Autodesk.AutoCAD.ApplicationServices
Autodesk.AutoCAD.DatabaseServices
Autodesk.AutoCAD.Colors
Autodesk.AutoCAD.Geometry

下面的示例代码演示使用和不适用 DLR 如何将直线添加到当前空间。

[CommandMethod("ADDLINE")]
public static void AddLine()
{
    // Get the current database
    Database acCurDb = HostApplicationServices.WorkingDatabase;

    // Start a transaction
    using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
    {
        // Open the Block table for read
        BlockTable acBlkTbl;
        acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
                                     OpenMode.ForRead) as BlockTable;

        // Open the Block table record Model space for write
        BlockTableRecord acBlkTblRec;
        acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
                                        OpenMode.ForWrite) as BlockTableRecord;

        // Create a line that starts at 5,5 and ends at 12,3
        using (Line acLine = new Line(new Point3d(5, 5, 0),
                                      new Point3d(12, 3, 0)))
        {
            // Add the new object to the block table record and the transaction
            acBlkTblRec.AppendEntity(acLine);
            acTrans.AddNewlyCreatedDBObject(acLine, true);
        }

        // Save the new object to the database
        acTrans.Commit();
    }
}

C# with Dynamic Language Runtime (DLR)

[CommandMethod("ADDLINE")]
public static void AddLine()
{
    // Get the current database
    dynamic acCurDb = HostApplicationServices.WorkingDatabase;

    // Create a dynamic reference to model or paper space
    dynamic acSpace = acCurDb.CurrentSpaceId;

    // Create a line that starts at 5,5 and ends at 12,3
    dynamic acLine = new Line(new Point3d(5, 5, 0),
                              new Point3d(12, 3, 0));

    // Add the new object to the current space
    acSpace.AppendEntity(acLine);
}

下面的示例代码演示使用和不使用 DLR 如何将层添加到当前数据库中。

[CommandMethod("ADDLAYER")]
public static void AddLayer()
{
    // Get the current database
    Database acCurDb = HostApplicationServices.WorkingDatabase;

    using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
    {
        // Returns the layer table for the current database
        LayerTable acLyrTbl;
        acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId,
                                     OpenMode.ForRead) as LayerTable;

        // Check to see if MyLayer exists in the Layer table
        if (acLyrTbl.Has("MyLayer") != true)
        {
            // Open the Layer Table for write
            acTrans.GetObject(acCurDb.LayerTableId, OpenMode.ForWrite);

            // Create a new layer named "MyLayer"
            using (LayerTableRecord acLyrTblRec = new LayerTableRecord())
            {
                acLyrTblRec.Name = "MyLayer";

                // Assign the ACI color 3 to the new layer
                Color acClr = Color.FromColorIndex(ColorMethod.ByAci, 3);
                acLyrTblRec.Color = acClr;

                // Add the new layer table record to the layer table and the transaction
                acLyrTbl.Add(acLyrTblRec);
                acTrans.AddNewlyCreatedDBObject(acLyrTblRec, true);
            }

            // Commit the changes
            acTrans.Commit();
        }

        // Dispose of the transaction
    }
}

C# with Dynamic Language Runtime (DLR)

[CommandMethod("ADDLAYER")]
public static void AddLayer()
{
    // Get the current database
    dynamic acCurDb = HostApplicationServices.WorkingDatabase;

    dynamic acLyrTbl = acCurDb.LayerTableId;

    // Check to see if MyLayer exists in the Layer table
    if (acLyrTbl.Has("MyLayer") != true)
    {
        // Create a new layer named "MyLayer"
        dynamic acLyrTblRec = new LayerTableRecord();
        acLyrTblRec.Name = "MyLayer";

        // Assign the ACI color 3 to the new layer
        dynamic acClr = Color.FromColorIndex(ColorMethod.ByAci, 3);
        acLyrTblRec.Color = acClr;

        // Add the new layer table record to the layer table
        acLyrTbl.Add(acLyrTblRec);
    }
}

下面演示了使用和不使用 DLR 如何逐步通过并列出当前空间中的所有对象。

[CommandMethod("LISTOBJECTS")]
public static void ListObjects()
{
    // Get the current document and database
    Document acDoc = Application.DocumentManager.MdiActiveDocument;
    Database acCurDb = HostApplicationServices.WorkingDatabase;

    using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
    {
        // Open the Block table record Model space for write
        BlockTableRecord acSpace;
        acSpace = acTrans.GetObject(acCurDb.CurrentSpaceId,
                                    OpenMode.ForRead) as BlockTableRecord;

        // Step through the current space
        foreach (ObjectId objId in acSpace)
        {
            // Display the class and current layer of the object
            Entity acEnt = (Entity)acTrans.GetObject(objId, OpenMode.ForRead);
            acDoc.Editor.WriteMessage("\nObject Class: " + acEnt.GetRXClass().Name +
                                      "\nCurrent Layer: " + acEnt.Layer +
                                       "\n");
        }
        acTrans.Commit();
    }
}

C# with Dynamic Language Runtime (DLR)

[CommandMethod("LISTOBJECTS")]
public static void ListObjects()
{
    // Get the current document and database
    dynamic acDoc = Application.DocumentManager.MdiActiveDocument;
    dynamic acCurDb = HostApplicationServices.WorkingDatabase;

    // Create a dynamic reference to model or paper space
    dynamic acSpace = acCurDb.CurrentSpaceId;

    // Step through the current space
    foreach (dynamic acEnt in acSpace)
    {
        // Display the class and current layer of the object
        acDoc.Editor.WriteMessage("\nObject Class: " + acEnt.GetRXClass().Name +
                                  "\nCurrent Layer: " + acEnt.Layer +
                                  "\n");
    }
}