I am using GetNestedEntity to select an AttributeReference and update the TextString. However, I would like to modify the routine to include other AttributeReferences on other BlockReferences. I would like to be able to access the BlockReference from the AttributeReference so I could implement different validations based on the Name of the BlockRefence. I have been trying to find a way to get this to work but I have been unable to do it. Can someone please indicate how to go about it.
Solved! Go to Solution.
Solved by norman.yuan. Go to Solution.
I assume that you use PromptNestedEntityResult object to obtain user picked AttributeReference' ObjectId.
According to the document and ObjectBrowser, there is a method: PromptNestedEntityResult.GetContainers(). It looks like the one we could use to find out which blockreference object owns the picked attribute. However, I tried this method with a simple block ( a circle with a couple of attributes) without sucess: the PromptNestedEntityResult.GetContainers() returns no container at all, although the picked nested entity is correctly an attribute.
But there is still a way to get what you want: AttributeReference.OwnerId will identify the BlockReference that owns the attributereference:
The code will look like:
Document dwg = Application.DocumentManager.MdiActiveDocument; Editor ed = dwg.Editor; Database db = dwg.Database; //Pick nested object - Attribute in a block PromptNestedEntityOptions opt = new PromptNestedEntityOptions("\nPick an attribute:"); opt.AllowNone = false; PromptNestedEntityResult res = ed.GetNestedEntity(opt); if (res.Status == PromptStatus.OK) { using (Transaction tran = db.TransactionManager.StartTransaction()) { AttributeReference att = tran.GetObject(res.ObjectId, OpenMode.ForRead) as AttributeReference; ed.WriteMessage("\nOwner ({0}): {1}", att.OwnerId.ToString(), att.OwnerId.ObjectClass.DxfName); BlockReference blk = tran.GetObject(att.OwnerId, OpenMode.ForRead) as BlockReference; ed.WriteMessage("\nPicked attribute is owned by block \"{0}\"", blk.Name); tran.Commit(); } }
Norman Yuan
An appendix to norman.yuan post:
AttributeReference.OwnerId gets the BlockReference that owns this AttributeReference.
var containers = PromptNestedEntityResult.GetContainers() gets the container(s) of the selected nested entity. If this entity is nested inside a block (innerBlock), and this block is nested inside another block (outerBlock), the result will be containers[0] = innerBlock.ObjectId, containers[1] = outerBlock.ObjectId. The first index is for the inner most nested block, the last index is for the outside overall block.
PromptNestedEntityResult.GetContainers() does NOT return anything if you pick on an AttributeReference (it may be a bug), but returns an array if you pick on any other entity (Line, Circle, DBText…). So GetContainers() will not use for attribute, instead we use AttributeReference.OwnerId to get the block reference of this attribute.
-Khoa
Thank you very much Norman. AttributeReference.OwnerId is exactly what I was looking for. I just needed to go back up one level to the BlockRefence.