在c#win中搜索树视图时出现问题。形成 [英] Problem in searching through a tree view in c# win. form

查看:59
本文介绍了在c#win中搜索树视图时出现问题。形成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的树是这样的: -

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数组总是返回空白。

推荐答案

这里的OP表达了在没有递归或某种形式的迭代的情况下在TreeView中查找任何TreeNode的目标:即不可能。可能的是通过构建节点的扁平化列表来最小化搜索TreeNode所涉及的计算。这里说明了这种技术。



当你执行像treeView1.Nodes.ContainsKey(node key)这样的代码时;您只搜索TreeView的特定TreeNodeCollection或TreeView中的节点。 'IndexOfKey方法以相同的方式工作。



从FrameWork 2.0开始,实现了'查找运算符:这是一个采用字符串的TreeNodeCollection类的方法这是节点的名称/键,以及第二个布尔值参数,如果为真,将以递归方式搜索所有子节点。



所以,要使用KeyNode14在整个TreeView中搜索TreeNode,您可以调用:treeView1.Nodes.Find(Node14,true)。当您执行此类搜索时,您将触发TreeView的基础数据结构,TreeNodeCollections和TreeNodes的内部递归迭代



创建所有TreeNode的flattened列表,并在每次添加或删除TreeNode时更新该列表:
The OP here expressed the goal of finding any TreeNode in a TreeView without recursion, or some form of iteration: that is impossible. What is possible is to minimize the computation involved in searching for TreeNodes by building a "flattened" list of the Nodes. That technique is illustrated here.

When you execute code like treeView1.Nodes.ContainsKey("node key"); you search only the specific TreeNodeCollection of either the TreeView, or a Node in the TreeView. The 'IndexOfKey method works in the same way.

Beginning with FrameWork 2.0, the 'Find operator was implemented: this is a method of the TreeNodeCollection Class that takes a string which is the Name/Key of a Node, and a second, boolean, parameter which, if true, will search recursively through all the sub-nodes.

So, to search the entire TreeView for a TreeNode with the Key "Node14," you can call: treeView1.Nodes.Find("Node14", true). When you perform such a search, you trigger the internal recursive iteration of the underlying data structure, the TreeNodeCollections, and TreeNodes, of the TreeView.

To create a "flattened" list of all TreeNodes, and update that list whenever a TreeNode is added, or deleted, to the Tree:
// 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中搜索树视图时出现问题。形成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆