By Augusto Goncalves (@augustomaia)
Basically we need to play with GetParentId and GetChilds methods to understand the hierarchy of the linked files. There is also a GetRootId method, but we’re not using here.
From the documentation, we can see that GetParentId results InvalidElementId for root elements, so we do a first run through to find all root elements. Then, for each get again and recursively get the childs again.
It’s not easy to show a hierarchical result, so let’s create a TreeView, as shown below. Note the result is similar to Revit UI. Cool!
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
// get active document
Document mainDoc = commandData.Application.ActiveUIDocument.Document;
// prepare to show the results...
TreeNode mainNode = new TreeNode();
mainNode.Text = mainDoc.PathName;
// start by the root links (no parent node)
FilteredElementCollector coll = new FilteredElementCollector(mainDoc);
coll.OfClass(typeof(RevitLinkInstance));
foreach (RevitLinkInstance inst in coll)
{
RevitLinkType type = mainDoc.GetElement(inst.GetTypeId()) as RevitLinkType;
if (type.GetParentId() == ElementId.InvalidElementId)
{
TreeNode parentNode = new TreeNode(inst.Name);
mainNode.Nodes.Add(parentNode);
GetChilds(mainDoc, type.GetChildIds(), parentNode);
}
}
// show the results in a form
System.Windows.Forms.Form resultForm = new System.Windows.Forms.Form();
TreeView treeView = new TreeView();
treeView.Size = resultForm.Size;
treeView.Anchor |= AnchorStyles.Bottom | AnchorStyles.Top;
treeView.Nodes.Add(mainNode);
resultForm.Controls.Add(treeView);
resultForm.ShowDialog();
return Result.Succeeded;
}
private void GetChilds(Document mainDoc, ICollection<ElementId> ids,
TreeNode parentNode)
{
foreach (ElementId id in ids)
{
// get the child information
RevitLinkType type = mainDoc.GetElement(id) as RevitLinkType;
TreeNode subNode = new TreeNode(type.Name);
parentNode.Nodes.Add(subNode);
// then go to the next level
GetChilds(mainDoc, type.GetChildIds(), subNode);
}
}