概要 - 動的言語ランタイムを使用する(.NET)

AutoCAD Managed .NET API を使用すると、.NET 4.0 で導入された動的言語ランタイム(DLR)を利用できます。

DLR を使用すると、オブジェクトに直接アクセスでき、次のようなことが必要ありません。

DLR の使用時には、オブジェクトの ObjectId を取得すると、そのオブジェクトのプロパティやメソッドに直接アクセスできます。ObjectId を取得した後は、次のデータ型の変数に ObjectId を代入できます。

ObjectId の取得方法は、オブジェクトがデータベースに保存される方法によって異なります。テーブルまたはディクショナリに格納されるオブジェクトの場合は、次のようにして ObjectId にアクセスできます。

次の例では、DLR でテーブルまたはディクショナリに格納されているオブジェクトにアクセスするための両方のオプションを示します。

C# の例

// 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 メソッドを使用する

DLR で GetEnumerator メソッドを使用するときは、使い終わった列挙子オブジェクトを明示的に破棄する必要があります。次の例では、使い終わった列挙子を破棄する方法を示します。

C# の例

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

LINQ クエリーを使用する

DLR では、LINQ クエリーを使用して、図面内のテーブルまたはディクショナリの内容をクエリーできます。次の例では、LINQ クエリーを使用して、現在の図面で特定の状態を割り当てられている画層をクエリーする方法を示します。

C# の例

[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 を使用しない場合に現在の空間に線分を追加する方法を示します。

C# の例

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

次の例では、DLR を使用した場合に現在の空間に線分を追加する方法を示します。

C# の例

[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 を使用しない場合に現在のデータベースに画層を追加する方法を示します。

C# の例

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

次の例では、DLR を使用した場合に現在のデータベースに画層を追加する方法を示します。

C# の例

[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 を使用しない場合に現在の空間内のすべてのオブジェクトを順番に処理して一覧表示する方法を示します。

C# の例

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

次の例では、DLR を使用した場合に現在の空間内のすべてのオブジェクトを順番に処理して一覧表示する方法を示します。

C# の例

[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");
    }
}