4

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

4 回答 4

2

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

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

问候

于 2012-10-01T13:44:32.660 回答
1

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

于 2012-10-12T13:38:19.113 回答
0

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

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

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

于 2012-09-21T22:29:13.337 回答
0

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

于 2015-08-05T20:40:39.417 回答