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 で GetEnumerator メソッドを使用するときは、使い終わった列挙子オブジェクトを明示的に破棄する必要があります。次の例では、使い終わった列挙子を破棄する方法を示します。
dynamic acCurDb = HostApplicationServices.WorkingDatabase; var acLtypeTbl = acCurDb.LinetypeTableId; var acTblEnum = acLtypeTbl.GetEnumerator(); ... acTblEnum.Dispose();
DLR では、LINQ クエリーを使用して、図面内のテーブルまたはディクショナリの内容をクエリーできます。次の例では、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();
}
}
次の例では、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
}
}
次の例では、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();
}
}
次の例では、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");
}
}