Issue
Using AutoCAD Architecture .NET API, I would like to list all classifications even if there are several levels to them. If child.Children.Count below is more than 0, I don't know how to act to get to the children.
Solution
A classification definition is stored in a form of tree structure. Given a top most node of a tree, you will need to visit each child node recursively. i.e.,
Public Sub ListClassificationTree(
ByRef tr As Transaction,
ByRef node As ClassificationTree,
ByVal sIndent As String)
...
If node.Children.Count > 0 Then
' this is an intermediate node, go through each branch.
Dim child As ClassificationTree
For Each child In node.Children
ListClassificationTree(tr, child, sIndent)
Next
...
The following command demonstrates how to list a tree structure of classification definition. Try, for example, with "Structural Usage" classification that comes with a metric template. The command lists the classification definitions that apply to either Mass Elements or Walls.
Public Class ACANETClassificationDef
'' list classification definitions.
<CommandMethod("ACANet", "ListClassificationDef", CommandFlags.Modal)> _
Public Sub ListClassificationDef()
'' Some basic things here
Dim ed As Editor =
Application.DocumentManager.MdiActiveDocument.Editor
Dim db As Database = HostApplicationServices.WorkingDatabase
'' Start a Transaction
Dim tr As Transaction = db.TransactionManager.StartTransaction
Try
'' get the dictionary for the classification definition,
'' and list of records in it
''
Dim dict As DictionaryClassificationDefinition =
New DictionaryClassificationDefinition(db)
Dim ids As ObjectIdCollection = dict.Records
Dim id As ObjectId
'' loop through each classification def
''
For Each id In ids
Dim obj As Object = tr.GetObject(id, OpenMode.ForRead, False, False)
Dim classCollDef As ClassificationDefinition = obj
'' as an example, check to see if class def is
'' applicable to Mass or Wall.
''
If classCollDef.AppliesToFilter.Contains("AecDbMassElem") Or _
classCollDef.AppliesToFilter.Contains("AecDbWall") Then
'' Found a classification definition that was applied to
'' AecDbMassElem/AcDbWall.
'' print out the name of the classification.
ed.WriteMessage(classCollDef.Name + vbCrLf)
'' Get the tree and print it out
Dim classTree As ClassificationTree =
classCollDef.ClassificationTree
ListClassificationTree(tr, classTree, "")
End If
Next
Catch ex As ApplicationException
tr.Abort()
System.Windows.Forms.MessageBox.Show(ex.Message)
Finally
tr.Dispose()
End Try
End Sub
'' Given a top most node of a tree, traverse the tree
''
Public Sub ListClassificationTree(
ByRef tr As Transaction,
ByRef node As ClassificationTree,
ByVal sIndent As String)
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
If node Is Nothing Then
Return
End If
'' let's get the name of the top most node.
''
If Not (node.Id.IsNull) Then
Dim classi As Classification =
CType(tr.GetObject(node.Id, OpenMode.ForRead), Classification)
Dim s As String = sIndent + classi.Name +
"(" + node.Id.Handle.ToString + ")" + vbCrLf
ed.WriteMessage(s)
End If
'' visit childen.
''
If node.Children.Count > 0 Then
'' this is an intermediate node, go through each branch.
Dim child As ClassificationTree
sIndent = sIndent + " "
For Each child In node.Children
ListClassificationTree(tr, child, sIndent)
Next
End If
End Sub