CAD开发者社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

ObjectARX 开发指南

关于使用动态语言运行时 (.NET)

2023-1-1 15:08| 发布者: admin| 查看: 827| 评论: 0|来自: AutoCAD

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

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

使用 DLR 允许您直接访问对象,而无需:

  • 打开对象进行读取或写入,然后在完成后关闭该对象。
  • 利用事务来提交所做的更改。

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

  • VB.NET 中的对象
  • C 语言中的动态#

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

  • 使用 ObjectId 的 Item 方法访问集合中的元素。
  • 创建对表或字典的 ObjectId 的引用并将其分配给变量,然后访问数组的元素。

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

VB.NET
'' Item method
Dim acCurDb As Object = HostApplicationServices.WorkingDatabase
Dim acMSpace As Object = acCurDb.BlockTableId.Item(BlockTableRecord.ModelSpace)

'' Reference an element directly from a collection
Dim acCurDb As Object = HostApplicationServices.WorkingDatabase
Dim acBlkTbl As Object = acCurDb.BlockTableId
Dim acMSpace As Object = acBlkTbl(BlockTableRecord.ModelSpace)
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

VB.NET
Dim acCurDb As Object = HostApplicationServices.WorkingDatabase
Dim acLtypeTbl As Object = acCurDb.LinetypeTableId
Dim acTblEnum As Object = acLtypeTbl.GetEnumerator()
...
acTblEnum.Dispose()
C#
dynamic acCurDb = HostApplicationServices.WorkingDatabase;
var acLtypeTbl = acCurDb.LinetypeTableId;
var acTblEnum = acLtypeTbl.GetEnumerator();
...
acTblEnum.Dispose();

使用 LINQ 查询

可以使用 LINQ 查询通过 DLR 查询图形中表或字典的内容。下面的示例演示如何使用 LINQ 查询来查询哪些图层在当前图形中指定了某些状态。

VB.NET
<CommandMethod("LINQ")> _
Public Sub LINQExample()
    Dim db As Object = HostApplicationServices.WorkingDatabase
    Dim doc As Object = Application.DocumentManager.MdiActiveDocument

    Dim layers = db.LayerTableId
    For i As Integer = 0 To 2
        Dim newrec As Object = layers.Add(New LayerTableRecord())
        newrec.Name = "Layer" + i.ToString()

        If i = 0 Then newrec.IsFrozen = True
        If i = 1 Then newrec.IsOff = True
    Next

    Dim OffLayers = From l In CType(CTypeDynamic(layers, GetType(IEnumerable(Of Object))),  _
                              IEnumerable(Of Object))
                           Where l.IsOff
                           Select l

    doc.Editor.WriteMessage(vbLf + "Layers Turned Off:")

    For Each rec As Object In OffLayers
        doc.Editor.WriteMessage(vbLf + " - " + rec.Name)
    Next

    Dim frozenOrOffNames = From l In CType(CTypeDynamic(layers, GetType(IEnumerable(Of Object))),  _
                                     IEnumerable(Of Object))
                                  Where l.IsFrozen = True Or l.IsOff = True
                                  Select l

    doc.Editor.WriteMessage(vbLf + "Layers Frozen or Turned Off:")

    For Each rec As Object In frozenOrOffNames
        doc.Editor.WriteMessage(vbLf + " - " + rec.Name)
    Next
End Sub
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);
}

Sample Code

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 sample code demonstrates how to add a Line to the current space; with and without DLR.

VB.NET

<CommandMethod("ADDLINE")> _
Public Sub AddLine()
    '' Get the current database
    Dim acCurDb As Database = HostApplicationServices.WorkingDatabase

    '' Start a transaction
    Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
        '' Open the current space for write
        Dim acSpace As BlockTableRecord
        acSpace = acTrans.GetObject(acCurDb.CurrentSpaceId, _
                                    OpenMode.ForWrite)

        '' Create a line that starts at 5,5 and ends at 12,3
        Using acLine As Line = New Line(New Point3d(5, 5, 0),
                                        New Point3d(12, 3, 0))

            '' Add the new object to the block table record and the transaction
            acSpace.AppendEntity(acLine)
            acTrans.AddNewlyCreatedDBObject(acLine, True)
        End Using

        '' Save the new object to the database
        acTrans.Commit()
    End Using
End Sub

VB.NET with Dynamic Language Runtime (DLR)

<CommandMethod("ADDLINE")> _
Public Sub AddLine()
    '' Get the current database
    Dim acCurDb As Object = HostApplicationServices.WorkingDatabase

    '' Create a dynamic reference to model or paper space
    Dim acSpace As Object = acCurDb.CurrentSpaceId

    '' Create a line that starts at 5,5 and ends at 12,3
    Dim acLine As Object = New Line(New Point3d(5, 5, 0),
                                    New Point3d(12, 3, 0))

    '' Add the new object to the current space
    acSpace.AppendEntity(acLine)
End Sub

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

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

The following sample code demonstrates how to add a Layer to the current database; with and without DLR.

VB.NET

<CommandMethod("ADDLAYER")> _
Public Sub AddLayer()
    '' Get the current database
    Dim acCurDb As Database = HostApplicationServices.WorkingDatabase

    '' Start a transaction
    Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
        '' Returns the layer table for the current database
        Dim acLyrTbl As LayerTable
        acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId, OpenMode.ForRead)

        '' Check to see if MyLayer exists in the Layer table
        If Not acLyrTbl.Has("MyLayer") Then
            '' Open the Layer Table for write
            acTrans.GetObject(acCurDb.LayerTableId, OpenMode.ForWrite)

            '' Create a new layer named "MyLayer"
            Using acLyrTblRec As LayerTableRecord = New LayerTableRecord()
                acLyrTblRec.Name = "MyLayer"

                '' Assign the ACI color 3 to the new layer
                Dim acClr As Color = 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)
            End Using

            '' Commit the changes
            acTrans.Commit()
        End If

        '' Dispose of the transaction
    End Using
End Sub

VB.NET with Dynamic Language Runtime (DLR)

<CommandMethod("ADDLAYER")> _
Public Sub AddLayer()
    '' Get the current database
    Dim acCurDb As Object = HostApplicationServices.WorkingDatabase

    Dim acLyrTbl As Object = acCurDb.LayerTableId

    '' Check to see if MyLayer exists in the Layer table
    If Not acLyrTbl.Has("MyLayer") Then
        '' Create a new layer named "MyLayer"
        Dim acLyrTblRec As LayerTableRecord = New LayerTableRecord()
        acLyrTblRec.Name = "MyLayer"

        '' Assign the ACI color 3 to the new layer
        Dim acClr As Color = Color.FromColorIndex(ColorMethod.ByAci, 3)
        acLyrTblRec.Color = acClr

        '' Add the new layer table record to the layer table
        acLyrTbl.Add(acLyrTblRec)
    End If
End Sub

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

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

The following demonstrates how to step through and list all the objects in the current space; with and without DLR.

VB.NET

<CommandMethod("LISTOBJECTS")> _
Public Sub ListObjects()
    '' Get the current document and database
    Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
    Dim acCurDb As Database = HostApplicationServices.WorkingDatabase

    '' Start a transaction
    Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
        '' Open the Block table record Model space for write
        Dim acSpace As BlockTableRecord
        acSpace = acTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForRead)

        '' Step through the current space
        For Each objId As ObjectId In acSpace
            '' Display the class and current layer of the object
            Dim acEnt As Entity = acTrans.GetObject(objId, OpenMode.ForRead)

            acDoc.Editor.WriteMessage(vbCrLf + "Object Class: " + acEnt.GetRXClass().Name + _
                                      vbCrLf + "Current Layer: " + acEnt.Layer + _
                                      vbCrLf)
        Next objId

        acTrans.Commit()
    End Using
End Sub

VB.NET with Dynamic Language Runtime (DLR)

<CommandMethod("LISTOBJECTS")> _
Public Sub ListObjects()
    '' Get the current document and database
    Dim acDoc As Object = Application.DocumentManager.MdiActiveDocument
    Dim acCurDb As Object = HostApplicationServices.WorkingDatabase

    '' Create a dynamic reference to model or paper space
    Dim acSpace As Object = acCurDb.CurrentSpaceId

    '' Step through the current space
    For Each acEnt As Object In CTypeDynamic(acSpace, GetType(System.Collections.IEnumerable))
        '' Display the class and current layer of the object
        acDoc.Editor.WriteMessage(vbCrLf + "Object Class: " + acEnt.GetRXClass().Name + _
                                  vbCrLf + "Current Layer: " + acEnt.Layer + _
                                  vbCrLf)
    Next acEnt
End Sub

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

路过

雷人

握手

鲜花

鸡蛋

最新评论

QQ|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 )

GMT+8, 2024-5-19 13:09

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部