The AutoCAD Managed .NET API allows you to utilize the Dynamic Language Runtime (DLR) that was introduced with .NET 4.0.
Using DLR allows you to access objects directly without having to:
You can access the properties and methods of an object directly once you have obtained its ObjectId when using DLR. After you have obtained an ObjectId, you can assign the ObjectId to a variable of the data type:
Obtaining an ObjectId varies by how the object is saved to the database. For objects stored in a table or dictionary, you can access its ObjectId by:
The following example shows both options for accessing an object that is stored in a table or dictionary with 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];
When using the GetEnumerator method with DLR, you need to explicitly dispose of the enumerator object once you are done working with it. The following sample demonstrates how to dispose of the enumerator when you are done with it.
dynamic acCurDb = HostApplicationServices.WorkingDatabase; var acLtypeTbl = acCurDb.LinetypeTableId; var acTblEnum = acLtypeTbl.GetEnumerator(); ... acTblEnum.Dispose();
You can utilize LINQ queries to query the contents of a table or dictionary in a drawing with DLR. The following example demonstrates the use of LINQ queries to query which layers have certain states assigned to them in the current drawing.
[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);
}
The sample code on this page uses the following name spaces:
Autodesk.AutoCAD.Runtime Autodesk.AutoCAD.ApplicationServices Autodesk.AutoCAD.DatabaseServices Autodesk.AutoCAD.Colors Autodesk.AutoCAD.Geometry
The following example demonstrates how to add a Line to the current space without 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();
}
}
The following example demonstrates how to add a Line to the current space with 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);
}
The following example demonstrates how to add a Layer to the current database without 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
}
}
The following example demonstrates how to add a Layer to the current database with 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);
}
}
The following example demonstrates how to step through and list all the objects in the current space without 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();
}
}
The following example demonstrates how to step through and list all the objects in the current space with 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");
}
}