Unfortunately, the Revit API does not currently provide any direct method to access the tag of a tagged element, and vice versa. Normally, I do not write about things that do not work. In this case, however, we have a couple of suggestions for workarounds. I would love to hear back from you whether you are already using any of the methods described below, or other techniques not described, in spite of the lack of direct API support. So this is the question:
Question: How can I find the tag associated with a given family instance, or the tagged element from a given tag?
I want to find a tag that was associated to a family instance through the API. I can go through the document and find both the family instance and the associated IndependentTag object, but I see no clear link between the two. The IndependentTag has a TagHeadPosition which I can match up with the family instance location, but I would hope there is a more accurate way to determine the relationship. When you delete the family instance, the IndependentTag also gets deleted, so Revit is maintaining some kind of link internally.
Can you tell me how to find the FamilyInstance through the IndependentTag or vice versa?
Answer: Unfortunately, the Revit API does not currently provide any direct method to access the relationship between a tag and the tagged element. Here are some workarounds that we currently suggest:
Here are the detailed descriptions of each of these approaches:
Use the Document.Delete() method to temporarily delete the tagged element, and retrieve the affected tag through the ElementIdSet returned.
The tagged element is regarded as a sort of parent object or host of the tag. Therefore, to find the tag of a given tagged element, we can delete the host, which in turn deletes all its tags and other child objects. One of the method overloads of Document.Delete() returns an ElementIdSet with the element ids of all the elements that will be deleted for the specific host element. Since we do not really want to delete any elements at all, we can wrap the deletion call in a transaction, retrieve the ElementIdSet, and abort the transaction and thus the deletion by calling AbortTransaction. This provides a way to access the associated tags of an element. For example, deleting the wall displayed below will return three tags: the wall tag, door tag and window tag. You can check the tag category to determine which one is the wall tag.
Unfortunately, this does not provide any way to access the host element from a given tag.
If the elements and their associated tags are generated by an application, the application can maintain an internal list of pairs of element ids for both.
When iterating over all database elements, they are returned in the sequential order in which they were added to the database. Normally the door and window tags will follow immediately after the door and window they are attached to. This holds both for elements generated through the user interface, as well as for many API-generated instances.
Collect all family instance elements and tags of the category you are interested in, for instance all doors and door tags, and pair them up by identical level and geometric proximity. That should generate a pretty reliable pairing in all normal cases.
Addendum: As I just pointed out to Martin, who kindly added a comment on it below, the Revit 2012 introduced some new methods and properties on the IndependentTag class to determine the elements referenced by the tag, including: