【问题标题】:Retrieving properties of AutoCAD object in C#在 C# 中检索 AutoCAD 对象的属性
【发布时间】:2012-09-13 03:40:41
【问题描述】:

我正在尝试从 C# 查询 AutoCAD 对象。我对能够获取给定对象的所有属性并输出它们很感兴趣。例如,在下面的代码片段中,我循环浏览屏幕上的所有项目,并仅反映它们的一流属性。我关心的对象通常具有一流的 AcadObject 属性,它似乎包含我所追求的数据。问题是这是一个 __ComObject 并且它的许多嵌套属性对象不通过反射提供属性。例如,obj.AcadObject.Connectors 似乎是一个连接器对象的集合,我对此非常感兴趣。我可以使用调试器反映到那个深度,但从那里我只能猜测 Connectors 集合的属性和它的对象(.Net 调试器确实显示了一个提示我的 Count 属性)。使用 C# 的动态关键字和 .Net 4 中内置的 DLR/COM 绑定器,我可以探测这些对象。例如,我可以使用动态表达式来抓取 obj.AcadObject.Connectors[0].Name,猜测它具有 name 属性。我愿意使用动态表达式来获取这些属性,但我首先需要知道这些属性是什么。我进行了很多研究,似乎缺少对这些对象外观的参考。还有一些其他的对象挂在 AcadObject 上,我也想导出。

var currentDocument = Application.DocumentManager.MdiActiveDocument;
var editor = currentDocument.Editor;
var database = editor.Document.Database;

var result = editor.SelectAll();

using (var transaction = database.TransactionManager.StartTransaction())
{
    foreach (var id in result.Value.GetObjectIds())
    {

        var obj = transaction.GetObject(id, OpenMode.ForRead);

        var properties = TypeDescriptor.GetProperties(obj.AcadObject).Cast<PropertyDescriptor>().OrderBy(prop => prop.Name);


        writer.WriteLine("{0} ID:{1}", obj.GetType().Name, obj.Id);
        writer.WriteLine("\r\n\r\n");

        foreach (var property in properties)
        {
            var propertyObject = property.GetValue(obj.AcadObject);
            writer.WriteLine("  {0} = {1}", property.Name, propertyObject);
        }

        writer.Write("\r\n\r\n\r\n");
    }
}

【问题讨论】:

    标签: c# autocad autocad-plugin


    【解决方案1】:

    如果您想从数据库中获取所有项目,请使用它:

    // Get all items from drawing Database. All ObjectIds will grouped by types;
    Database db = Application.DocumentManager.MdiActiveDocument.Database;           
    Dictionary<string, List<ObjectId>> dict = new Dictionary<string, List<ObjectId>>();
    using (Transaction t = db.TransactionManager.StartTransaction()) {
        for (long i = db.BlockTableId.Handle.Value; i < db.Handseed.Value; i++) {
            ObjectId id = ObjectId.Null;
            Handle h = new Handle(i);
            if (db.TryGetObjectId(h, out id)) {
                string type = id.ObjectClass.Name;
                if (!dict.Keys.Contains(type))
                    dict.Add(type, new List<ObjectId>());
                dict[type].Add(id);
            }
        }
        t.Commit();
    }
    

    问候

    【讨论】:

    • 我实际上是通过获取 ModelSpace 的 BlockTableRecord 来获取我想要的所有元素。我的问题是枚举我检索到的对象中的所有属性,如宽度、高度、直径等。由于我得到了各种类型的绘图对象(管道、管道、管道配件、网格、线等)我不知道是什么属性是预先设置的,所以我想要一种动态的方式来查找它们。
    【解决方案2】:

    您可能会发现 MgdDbg 实用程序在探索给定图形的数据库时特别有用...取决于您所追求的内容以及您的 AutoCAD 版本,因为事件等是硬编码的,而不是正如托尼所说的那样动态here

    【讨论】:

      【解决方案3】:

      这不是一个完美的答案,但我会把它放在这里,以便它可以帮助其他人。使用即时窗口,我将 obj.Acad 转换为动态,然后向下引用到有问题的对象,例如 Connectors[0]。那时我将它重铸成一个物体,并能够用手表检查它。示例代码,因为它将在立即窗口中运行,并且在 obj 集之后带有调试中断:

      dynamic acad = obj.AcadObject;
      object connector0 = (object)acad.Connectors[0];
      

      我能想到的最好的办法是 DLR 的 COM 绑定器正在为我整理内容,然后一旦我将它转换回 .Net 调试器就可以找出属性。我正在努力让这个发现与反射一起工作......

      【讨论】:

        【解决方案4】:

        您可以尝试使用此实用程序来获取有关您的 COM 对象的更多信息:http://www.codeproject.com/Articles/523417/Reflection-with-IDispatch-based-COM-objects

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-09-28
          • 2020-06-09
          • 2017-07-11
          • 2018-08-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多