通过AssocArray.GetAssociativeArray的静态方法获取对象的阵列,然后通过SourceEntities源实体来获取块名。
using System; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.EditorInput; // This line is not mandatory, but improves loading performances [assembly: CommandClass(typeof(Rivilis.CheckAssocArray))] namespace Rivilis { public class CheckAssocArray { [CommandMethod("CAR")] public void MyCommand() { // Put your command code here Document doc = Application.DocumentManager.MdiActiveDocument; if (doc == null) return; Editor ed = doc.Editor; PromptEntityOptions prOpt = new PromptEntityOptions("Select Assoc Array: "); prOpt.SetRejectMessage("Not a Assoc Array"); prOpt.AddAllowedClass(typeof(BlockReference), true); PromptEntityResult prRes = ed.GetEntity(prOpt); if (prRes.Status == PromptStatus.OK) { AssocArray asArr = AssocArray.GetAssociativeArray(prRes.ObjectId); if (asArr == null) { ed.WriteMessage(" Not a Assoc Array"); return; } ObjectIdCollection ids = asArr.SourceEntities; if (ids.Count >= 1) { ObjectId id = ids[0]; // Check only first entity in Array if (id.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(BlockReference)))) { using (BlockReference br = id.Open(OpenMode.ForRead) as BlockReference) { using (BlockTableRecord btr = br.DynamicBlockTableRecord.Open(OpenMode.ForRead) as BlockTableRecord) { ed.WriteMessage(" BlockName = {0}", btr.Name); } } } else { ed.WriteMessage(" Assoc Array has not BlockReference"); } } } } } }
如果阵列后替换过块,原文是通过炸开阵列来判段。
using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; using System.Linq; #pragma warning disable 0618 // This line is not mandatory, but improves loading performances [assembly: CommandClass(typeof(Rivilis.CheckAssocArray))] namespace Rivilis { public class CheckAssocArray { public string GetBlockNameInBlock(BlockReference br) { string name = null; using (BlockTableRecord btr = br.DynamicBlockTableRecord.Open(OpenMode.ForRead) as BlockTableRecord) { name = btr.Name; // If block has only one entity == BlockReference // then getting name of this block if (btr.Cast<ObjectId>().Count() == 1) { ObjectId id = btr.Cast<ObjectId>().ElementAt(0); if (id.ObjectClass == RXClass.GetClass(typeof(BlockReference))) { using (BlockReference brInt = id.Open(OpenMode.ForRead) as BlockReference) using (BlockTableRecord btrInt = brInt.DynamicBlockTableRecord.Open(OpenMode.ForRead) as BlockTableRecord) { name = btrInt.Name; } } } } return name; } [CommandMethod("CAR")] public void MyCommand() { // Put your command code here Document doc = Application.DocumentManager.MdiActiveDocument; if (doc == null) return; Editor ed = doc.Editor; PromptEntityOptions prOpt = new PromptEntityOptions("Select Assoc Array: "); prOpt.SetRejectMessage("Not a Assoc Array"); prOpt.AddAllowedClass(typeof(BlockReference), true); PromptEntityResult prRes = ed.GetEntity(prOpt); if (prRes.Status != PromptStatus.OK) return; if (!AssocArray.IsAssociativeArray(prRes.ObjectId)) { ed.WriteMessage(" Not a Assoc Array"); return; } using (BlockReference br = prRes.ObjectId.Open(OpenMode.ForRead) as BlockReference) { using (DBObjectCollection brs = new DBObjectCollection()) { br.Explode(brs); if (brs != null && brs.Count > 0) { int i = 0; foreach (DBObject obj in brs) { if (obj is BlockReference && (obj as BlockReference).Layer != "*ADSK_ASSOC_ENTITY_BACKUPS") { ed.WriteMessage(" {0} - {1}", i++, GetBlockNameInBlock(obj as BlockReference)); } obj.Dispose(); } } } } } } }
应该有更好的方式,不过得理解AutoCAD Associative Framework的组织。
原始链接:https://forums.autodesk.com/t5/net/getting-block-name-from-associative-array/m-p/8479018