我试图在TreeView中搜索特定字符串,一旦找到了节点的索引,我希望返回其索引并更改该特定节点的背景颜色,但是我当前的代码没有似乎返回任何匹配,除非它是根节点:
private void ApplyRulesetColors()
{
foreach (var rule in dictOverwriteEntries)
{
int iResultIndex = SearchTreeView(rule.Key, tvDirectoryStructure.Nodes);
if (iResultIndex > -1)
{
switch (rule.Value)
{
case Operations.Overwrite:
tvDirectoryStructure.Nodes[iResultIndex].BackColor = Color.Red;
break;
case Operations.Delete:
break;
case Operations.None:
break;
default:
break;
}
}
}
}
这是应该搜索树视图的函数:
private int SearchTreeView(string p_sSearchTerm, TreeNodeCollection p_Nodes)
{
foreach (TreeNode node in p_Nodes)
{
if (node.Text == p_sSearchTerm)
{
return node.Index;
}
if (node.Nodes.Count > 0)
SearchTreeView(p_sSearchTerm, node.Nodes);
}
return -1;
}
此时只会在根节点值上匹配并返回0,即使(据我所知)它应该搜索整个树,包括子节点。
谢谢。
答案 0 :(得分:2)
您的代码中存在两个问题:
-1
。Index
,这是节点的父子集合中的索引,而不是全局索引。我建议改为返回TreeNode
本身。像这样改变你的方法:
private TreeNode SearchTreeView(string p_sSearchTerm, TreeNodeCollection p_Nodes)
{
foreach (TreeNode node in p_Nodes)
{
if (node.Text == p_sSearchTerm)
return node;
if (node.Nodes.Count > 0)
{
TreeNode child = SearchTreeView(p_sSearchTerm, node.Nodes);
if (child != null) return child;
}
}
return null;
}
并使用它:
private void ApplyRulesetColors()
{
foreach (var rule in dictOverwriteEntries)
{
TreeNode resultNode = SearchTreeView(rule.Key, tvDirectoryStructure.Nodes);
if (resultNode != null)
{
switch (rule.Value)
{
case Operations.Overwrite:
resultNode.BackColor = Color.Red;
break;
case Operations.Delete:
break;
case Operations.None:
break;
default:
break;
}
}
}
}
但请注意,此代码只会找到第一个匹配的节点。我不知道您的树是否可能包含多个具有相同Text
的节点。在这种情况下,您应该使用另一个属性来标识节点。
答案 1 :(得分:2)
您需要返回TreeNode
本身而不是它的索引,因为索引是相对于定位节点的父节点。此外,您的递归SearchTreeView
在递归调用期间找到它时不会返回该元素。下面的代码将起作用并返回TreeNode
本身,您可以根据需要设置样式。
您可能希望知道您的方法效率不高,因为您需要按照列表中的规则多次迭代树。如果迭代树一次,然后匹配列表中每个节点的规则,则可能更有效。您的代码可能是应用访客模式的好例子:http://www.dofactory.com/net/visitor-design-pattern
无论如何,这是正确的SearchTreeView
:
private TreeNode SearchTreeView(string p_sSearchTerm, TreeNodeCollection p_Nodes)
{
foreach (TreeNode node in p_Nodes)
{
if (node.Text == p_sSearchTerm)
{
return node;
}
if (node.Nodes.Count > 0)
{
var result = SearchTreeView(p_sSearchTerm, node.Nodes);
if (result != null)
{
return result;
}
}
}
return null;
}