我正在try 用C#从类的树中构建一个WinForms树视图,它能够通过从类 struct 中搜索标记来从树视图中 Select 一项.
我一直在try 实现一个Update
方法,以便在需要时以递归方式重新绘制整个树.
首先:
我在基本树中的所有类都是从一个名为Node
的抽象类派生的.
Node类包含一个name (string)
、_id (byte)
和一个子 node 列表:
abstract class Node
{
byte _id;
string _name;
List<Node> _children = new List<Node>();
public Node()
{
this.ID = (byte)Iterator.GenerateID;
}
public void AddChild(Node child)
{
_children.Add(child);
}
}
Node构造函数分配一个唯一的ID.(目前为止这工作正常). 这个类的任何派生类都可以成功地生成一个ID,而不会覆盖任何东西.
在我的主表单中,我有一个根 node 列表:private List<Node> _root = new List<Node>();
和用于存储当前 Select 的 node 的变量:private Node _selection;
我用来遍历 node 列表并递归地将它们添加到我的表单的TreeView中的Update方法;tv_scene
:
private void UpdateTree()
{
tv_scene.BeginUpdate();
tv_scene.Nodes.Clear();
tv_scene.Nodes.Add("Scene");
foreach (Node n in _root)
{
TreeNode tn = new TreeNode(n.Name);
tn.Tag = n.ID;
if (n.Children.Count != 0)
{
AddTreeItem(n, tn);
}
tv_scene.Nodes[0].Nodes.Add(tn);
}
tv_scene.ExpandAll();
tv_scene.EndUpdate();
}
private void AddTreeItem(Node node, TreeNode parent)
{
TreeNode tn = new TreeNode(node.Name);
tn.Tag = node.ID;
parent.Nodes.Add(tn);
foreach (Node n in node.Children)
{
if (n.Children.Count != 0)
{
AddTreeItem(n, tn);
}
}
return;
}
当需要对树形视图进行更新时,我会呼叫UpdateTree()
.
在我的用例中,我将唯一ID作为字符串存储在TreeView node 的"tag"成员中,然后将其转换回一个字节,以便在Node树中搜索由TreeView中的项目表示的对象.
此搜索也以递归方式完成:
private Node GetNodeByID(List<Node> nodes, byte? id)
{
foreach (Node n in nodes)
{
if (n.ID == id)
return n;
if (n.Children.Count != 0)
{
Node result = GetNodeByID(n.Children, id);
if (result != null)
return result;
}
}
return null;
}
我通过将TreeView中所选项目的标记解析回一个字节来调用此搜索函数,如下所示:_selection = GetNodeByID(_root, (byte)UInt32.Parse(tv_scene.SelectedNode.Tag.ToString()));
将子 node 添加到根列表时,代码运行得很好,但每当我try 将子 node 添加到所述项目(2层深)时,新添加的子 node 显示的名称与其父 node 的名称相同,尽管使用正确的ID和名称进行了正确的初始化.另外,如果我try 用_selection = GetNodeByID(_root, (byte)UInt32.Parse(tv_scene.SelectedNode.Tag.ToString()));
来 Select 该 node ,我会得到它的父 node .我也不能向所述 node 添加任何子 node ,并且树最多保持2层深.
示例:
当我打印新的item函数的输出和结果GetNodeByID()
时:
Node added: [ID:0, Name:Root0] //Adding first node(success)
Node added: [ID:1, Name:Root1] //Adding second node(success)
Item selected: [ID:0, Name:Root0] //Selecting the first node with GetNodeByID(success)
Node added: [ID:2, Name:Child0] //Adding a child to the selected node (?)
Item selected: [ID:0, Name:Root0] //Trying to select node [ID:2, Name:Child0](fail)
我非常确定我的递归方法中的逻辑在某种程度上存在根本缺陷,我只是看不出来.这里是否发生了什么阻止我显示&; Select 超过2个分支深度的 node ?