Основная проблема при заполнении Treeview заключается в том, выполняете ли вы полную загрузку всех узлов или реализуете какой-то подход с отложенной загрузкой при расширении каждого узла.
Заполнение полного дерева будет работать приемлемо только в том случае, если у вас менее 500 узлов, и количество узлов не будет расти. В противном случае подход с отложенной загрузкой лучше.
Самый простой способ сделать это - заполнить дочерние узлы в событии BeforeExpand. Однако TreeView не будет отображать знак +/-, указывающий на то, что у узла есть дочерние элементы, пока вы фактически не добавите к нему дочерние элементы. Поэтому, заполняя родительский узел, вы должны проверить, есть ли у логического элемента (строки данных) дочерние элементы, и если он есть, добавить фиктивный узел.
Я обнаружил, что наследование пользовательского класса от TreeNode - это один из самых простых подходов к определению фиктивного узла. Затем вы можете проверить это в BeforeExpand (), используя оператор Is.
Затем, когда пользователь расширяет родительский узел, в событии BeforeExpand проверьте, существует ли фиктивный узел, если он есть, и заполняйте фактические узлы. Для каждого из этих узлов проверьте наличие дочерних элементов и заполните свойство tag и фиктивный узел, если требуется.
Установите для свойства Tag для каждого узла какой-либо значимый объект / данные. Это позволит вам при необходимости легко заполнять дочерние узлы. Просто имейте в виду, что это объект типа, вам нужно будет при необходимости правильно привести его к фактическому типу данных.