C# 树在我添加到每个节点时会复制每个节点
本文关键字:节点 复制 添加 | 更新日期: 2023-09-27 17:55:44
所以基本上我正在做的是向后构建一棵树。我从叶子开始,然后添加它们的父母,然后是他们的(最后是一棵 3 级的树)。
我添加叶子没有问题(我查询数据库,并为每个条目创建一个 TNode(TreeNode 类的扩展),然后将它们添加到树中)。此步骤中没有重复 - 当我去添加叶子的父母时,重复就会发生。
我遍历叶子树,当两片叶子有不同的节号(只是一个我想按数分组的数字)时,我几乎会创建一个新的父节点。
该程序正在做的是在每个父节点下创建每个叶节点的两组,因此它看起来像这样:
它不会让我发布图像,所以我会尝试用文本绘制树:像这样
第 1 部分 儿童 1-1 儿童 1-2 儿童 1-3 儿童 1-1 儿童 1-2 儿童 1-3 第 2 部分 儿童 2-1 儿童 2-2 儿童 2-1 儿童 2-2
这是正在执行此操作的代码...这真的很奇怪,因为当我调试它时,每个节点的子节点数量每次都按预期增长一个,但是一旦添加了所有父节点,每个叶子有两个......
我也尝试将倒计时削减为仅 1,它增加了一个父母,并且它有一个孩子,这是重复的......
无论如何,代码:
请注意,switch 语句并不重要,它们只是设置新节点的文本
private void addLvl1Nodes() {
int i = 0;
TNode newNode = null;
int count = tv_master.Nodes.Count;
while (i < count) {
TNode tn = (TNode)tv_master.Nodes[i];//get current node
//if i = 0, then newNode has not been set, so make a new one!
if ((i == 0)||
(tn.Section != ((TNode)tv_master.Nodes[i-1]).Section )||
(tn.Text.Substring(0, 1) != tv_master.Nodes[i - 1].Text.Substring(0, 1))){
newNode = new TNode("");
tv_master.Nodes.Add(newNode);
switch (tn.Text.Substring(0, 1)) {
case "1": newNode.Text = "Part One"; break;
case "2": newNode.Text = "Part Two"; break;
case "3": newNode.Text = "Part Three"; break;
}
newNode.Section = tn.Section;
}
newNode.Nodes.Add(tn);
i++;
}
}
希望有人以前遇到过类似的错误 - 因为我找不到解决方案。
多谢!
+++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++对于遇到类似问题的任何人来说,这是我代码的最终副本,现在可以按预期工作:)
private void addLvl1Nodes() {
TNode newNode = null;
List<TNode> nodes = tv_master.Nodes.Cast<TNode>().ToList();
tv_master.Nodes.Clear();
for(int i = 0; i<nodes.Count; i++){
TNode tn = nodes[i];
if ((i == 0) ||
(tn.Section != nodes[i-1].Section) ||
(tn.Text[0] != nodes[i-1].Text[0])) {
newNode = new TNode("");
tv_master.Nodes.Add(newNode);
switch (tn.Text[0]) {
case '1': newNode.Text = "Part One"; break;
case '2': newNode.Text = "Part Two"; break;
case '3': newNode.Text = "Part Three"; break;
}
newNode.Section = tn.Section;
}
newNode.Nodes.Add(tn);
}
}
在进行此调用之前,您可能需要从其旧父级中删除 tn:
newNode.Nodes.Add(tn);
否则,您实际上不会有两个单独的 tn(子节点)实例,但它会在层次结构中多次显示。 (一次直接在tv_master下,一次在新创建的节点下。
只保留两个单独的节点列表(或树)可能是有意义的。 一个用于保存新创建的父节点,另一个用于保存叶节点。 然后,您可以在最后将所有内容连接起来。 也许像这样开始你的循环:
List<TNode> listLeafNodes = new List<TNode>(tv_master.Nodes);
tv_master.Nodes.Clear();
for( int i=0; i<listLeafNodes.Count; ++i )
{
...
}
当然,我不确定你用的是什么类来做 TNode 和 tv_master。 我在MSDN上看到的TNode界面似乎没有任何.节点属性。 此外,似乎至少有 3 个不同的 TreeView 类。 TNode 的完全限定类名和tv_master的定义可能有助于我们更好地理解事物。
正如 ebyrob 已经解释的那样,您将相同的节点添加到树中两次,因此在开始时清除初始节点列表会有所帮助。
为了补充他们的答案,您的初始节点也被"移动"到根之外的原因是TreeNodeCollection.Add
方法不仅将节点添加到其内部数组中,而且还更改节点的私有parent
字段以指向其新的父节点。
这样,每个初始节点都会从树中的两个位置(根节点和第一个子节点)引用,但其 Parent
属性使两个引用都在其父节点下呈现。
这似乎不是一个真正的解决方案,但它仍然可以帮助您。通过分析我遇到的您提供的代码,您可以使用相同的节点集合来获取子元素以及附加新节点。但子元素永远不会从原始节点集合中删除。因此,基本上您拥有子节点以及同一集合中各节的新节点。
应从集合中删除已处理的子元素。但请注意,这样做时,while 循环中的表达式必须改变。
此外,您可以简化以下行
tn.Text.Substring(0, 1)
喜欢这个
tn.Text[0]
这也适用于代码示例中后面第一个字符的比较。