Я пытаюсь создать TreeView Winforms из дерева классов на C# с возможностью выбора элемента из TreeView путем поиска его тега в структуре класса.
Я пытался реализовать метод Update для рекурсивной перерисовки всего дерева, когда это необходимо.
Прежде всего: Все мои классы в базовом дереве являются производными от абстрактного класса Node. Класс Node содержит имя (строка), _id (байт) и список дочерних узлов:
абстрактный класс Node { байт _id; строка _имя; List _children = новый List(); публичный узел() { this.ID = (байт)Iterator.GenerateID; } public void AddChild (дочерний узел) { _дети.Добавить(ребенок); } } Конструктор Node присваивает уникальный идентификатор. (пока это работает нормально). Любые производные этого класса успешно генерируют идентификатор, ничего не переопределяя.
В моей основной форме у меня есть список корневых узлов: private List _root = new List(); и переменная для хранения текущего выбранного узла: private Node _selection;
Метод Update, который я использую для перемещения по списку узлов и рекурсивного добавления их в TreeView моей формы; tv_scene:
private void UpdateTree() { tv_scene.BeginUpdate(); tv_scene.Nodes.Clear(); tv_scene.Nodes.Add("Сцена"); foreach (узел n в _root) { TreeNode tn = новый TreeNode(n.Name); tn.Tag = n.ID; если (n.Children.Count != 0) { AddTreeItem (п, тн); } tv_scene.Nodes[0].Nodes.Add(tn); } tv_scene.ExpandAll(); tv_scene.EndUpdate(); } Private void AddTreeItem (узел Node, родительский элемент TreeNode) { TreeNode tn = новый TreeNode(node.Name); tn.Tag = node.ID; родитель.Узлы.Добавить(ТН); foreach (узел n в узле.Children) { если (n.Children.Count != 0) { AddTreeItem (п, тн); } } возвращаться; } Я вызываю UpdateTree(), когда требуется обновление TreeView. В моем случае я сохраняю уникальный идентификатор в элементе «Тег» узла TreeView в виде строки, а затем преобразую его обратно в байт, чтобы выполнить поиск в дереве узлов объекта, представленного элементом в TreeView. . Этот поиск также выполняется рекурсивно:
частный узел GetNodeByID (список узлов , байт? идентификатор) { foreach (узел n в узлах) { если (n.ID == идентификатор) вернуть н; если (n.Children.Count != 0) { Результат узла = GetNodeByID(n.Children, id); если (результат!= ноль) вернуть результат; } } вернуть ноль; } Я вызываю эту функцию поиска, анализируя тег выбранного элемента в TreeView обратно в байт, например:_selection = GetNodeByID(_root, (byte)UInt32.Parse(tv_scene.SelectedNode.Tag. ToString())); Код работает нормально при добавлении дочерних узлов в корневой список, но всякий раз, когда я пытаюсь добавить дочерние узлы к указанным элементам (глубиной 2 уровня). Недавно добавленный дочерний узел отображается с тем же именем, что и родительский, несмотря на то, что он правильно инициализирован с правильным идентификатором. и Имя. Кроме того, если я попытаюсь выбрать указанный узел с помощью _selection = GetNodeByID(_root, (byte)UInt32.Parse(tv_scene.SelectedNode.Tag.ToString()));, я получу его родительский узел. Я также не могу добавить дочерних элементов к указанному узлу, и дерево остается глубиной максимум 2 уровня.
Пример:

Когда я печатаю вывод функции нового элемента и результат GetNodeByID():
Добавлен узел: [ID:0, Name:Root0] //Добавление первого узла (успех) Добавлен узел: [ID:1, Имя:Root1] //Добавление второго узла (успешно) Выбранный элемент: [ID:0, Name:Root0] //Выбор первого узла с помощью GetNodeByID(успех) Добавлен узел: [ID:2, Name:Child0] //Добавление дочернего узла к выбранному узлу (?) Выбранный элемент: [ID:0, Name:Root0] //Попытка выбрать узел [ID:2, Name:Child0](неудача) Я совершенно уверен, что логика моих рекурсивных методов в чем-то фундаментально ошибочна, но я просто этого не вижу. Что-то здесь мешает мне показывать и выбирать узлы глубиной более двух ветвей?
Мобильная версия