关于使用动态语言运行时 (. net)
AutoCAD Managed .NET API允许您使用使用. NET 4.0 引入的动态语言运行时 (DLR)。
使用DLR可以直接访问对象, 而无需:
- 打开一个对象进行读取或写入, 然后在完成后关闭该对象。
- 利用事务提交所做的更改。
在使用DLR时获得对象的ObjectId后, 可以直接访问对象的属性和方法。获得ObjectId后, 可以将ObjectId分配给数据类型的变量:
- Object in VB.NET
- dynamic in C#
获取ObjectId因对象保存到数据库的方式而异。对于存储在表或字典中的对象, 可以通过以下方式访问其ObjectId:
- 使用ObjectId的 item 方法访问集合中的元素。
- 创建对表或字典的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方法
在将 GetEnumerator 方法与DLR一起使用时, 需要在使用完枚举器对象后显式释放该对象。下面的示例演示如何在完成枚举器时对其进行处置。
C# dynamic acCurDb = HostApplicationServices.WorkingDatabase; var acLtypeTbl = acCurDb.LinetypeTableId; var acTblEnum = acLtypeTbl.GetEnumerator(); ... acTblEnum.Dispose();
使用LINQ查询
您可以利用LINQ查询在使用DLR的图形中查询表或字典的内容。下面的示例演示如何使用 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如何将直线添加到当前空间。
[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"); } }