问题描述
我的树是这样的: -
My tree is like this:-
Science
Biology
Human
Physics
Chemistry
现在我想搜索整个树中是否存在 Human (没有迭代[for,while,do while or foreach] ) 。怎么做?
我试过
1)
now i want to search if Human exists in the whole tree (without iteration [for,while,do while or foreach]). How to do so?
I tried
1)
bool isExists = treeView1.Nodes.ContainsKey("Human");
但是 bool 变量总是返回false。
2)
but the bool variable always returned false.
2)
TreeNode[] Tnarray = treeView1.Nodes.Find("Human", true);
但是 TreeNode数组总是返回空白。
推荐答案
// list of all TreeNodes
private List<TreeNode> flatNodeList = new List<TreeNode>();
// create the flattened node list using recursion
private void createFlatList(TreeNodeCollection theNodes)
{
foreach (TreeNode theNode in theNodes)
{
flatNodeList.Add(theNode);
if(theNode.Nodes.Count != 0) createFlatList(theNode.Nodes);
}
}
// build the flattened list in the Form_Load EventHandler
private void Form1_Load(object sender, EventArgs e)
{
createFlatList(treeView1.Nodes);
}
一旦拥有了所有TreeNode的列表,就可以搜索它,并使用所有常规的通用List运算符;您可以使用Linq来执行复杂的查询和分析,并根据条件选择节点的子集等。
这就留下了你的问题当用户在运行时添加或删除节点时更新平面列表;很明显,每次添加或删除单个节点时,您都不希望以递归方式重新构建整个列表!
更新的一种方法是定义自己的添加和删除TreeNodes的方法:
Once you have that List of all TreeNodes, you can search it, and use all the regular generic List operators; you can use Linq on it to do complex queries, and analysis, and select sub-sets of nodes based on conditions, etc.
That leaves the question of how you update the flat-list as the user adds, or deletes, nodes at run-time; obviously you don't want to re-build the entire list recursively every time a single node is added, or deleted !
One way to update is to define your own methods for add, and delete, TreeNodes:
private void AddNode(TreeNodeCollection theNodes, string key)
{
TreeNode newNode = new TreeNode(key);
flatNodeList.Add(newNode);
theNodes.Add(newNode);
}
private void DeleteNode(TreeNode theNode)
{
if(! flatNodeList.Contains(theNode)) throw new KeyNotFoundException("Invalid Node in DeleteNode");
flatNodeList.Remove(theNode);
// are we removing a top-level (root) Node ?
// if so, the Parent is 'null
if (theNode.Level == 0)
{
theNode.TreeView.Nodes.Remove(theNode);
}
else
{
// removing a Node that has a Parent Node
theNode.Parent.Nodes.Remove(theNode);
}
}
您可以采用此处演示的原则并使用它们添加可能更新平面列表的其他方法,例如'AddRange。
注意:并非每个使用标准TreeView的应用程序都可以从...中避免使用查找运算符按照此处显示的技术进行搜索。但是,所有节点的扁平列表还有许多其他可能的用途。
如果我使用的TreeView具有极大数量的TreeNodes,则深度嵌套,经常需要进行搜索,我肯定会使用这里显示的技术。
在我写的一些实际应用程序中,我不仅创建了一个扁平的TreeNodes列表,我创建了一个形式为Dictionary< int,List< treenode>>>的数据结构。 ...这是以相同的递归方式动态构建的,我构建了所有TreeNode的扁平List,并最终在TreeView中的每个级别包含一个单独的TreeNodeCollection节点。
您可以使用的其他技术包括对WinForms TreeView进行子类化,并覆盖您需要修改的方法以更新扁平列表。
You can take the principles demonstrated here and use them to add other methods that might update the flat list, like 'AddRange.
Note: not every application using the standard TreeView might benefit ... much ... from avoiding using the 'Find operator to search by the techniques shown here. However, there are many other possible uses for a flattened list of all the Nodes.
If I were using a TreeView with an extremely large number of TreeNodes, deeply nested, with frequent need to do searches, I would certainly use the techniques shown here.
In some real applications I have written, not only have I created a flattened list of TreeNodes, I've created a data structure of the form Dictionary<int,List<treenode>>> ... this is built dynamically in the same recursive way I build a flattened List of all the TreeNodes, and ends up containing a separate TreeNodeCollection for nodes at each level in the TreeView.
Other techniques you can use include sub-classing the WinForms TreeView, and over-riding the methods you need to modify to keep a flattened list updated.
这篇关于在c#win中搜索树视图时出现问题。形成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!