从TreeView深处获取node.value

时间:2012-07-20 17:08:03

标签: c# asp.net treeview

我有一个TreeView,包含文件夹和文件,它们都存储在数据库中。我现在使用AjaxToolkit中的自动完成搜索功能创建了一个搜索功能。一切都很好,除了我正在努力寻找具有搜索价值的节点。我现在必须是一个递归方法,但我不知道该怎么做。

所以,问题是。如何根据我已有的节点值在树视图中找到节点。我还需要获取所有父节点值。所以我可以从中选择节点。

以下是一些代码(在搜索完成后的回发中):

 else
            {   
                // postBack handler for AJAX AutoComplete Extender - JavaScript call: AutoCompletedClientItemSelected
                if (Request.Form["__EVENTTARGET"] != null &&
                Request.Form["__EVENTTARGET"] == "AutoCompleteExtender" &&
                Request.Form["__EVENTARGUMENT"] != null)
                {   
                    //i have the value for the node, but i need to search for it here, 
                    //and i also need the node-values from all the parents. I need the "path"
                    string nodeValue = Session["NodeValueFromSearchForm"].ToString();
                    string nodePath = "";

                    foreach (TreeNode node in TreeViewFolders.Nodes)
                    {
                        if (node.Value == nodeValue)
                        {
                            //I'm stuck here
                            nodePath += "\\s" + node.Value;

                        }
                    }

                    string prompt = String.Format("<script>{0}{1}{2}</script>", "javascript:__doPostBack('TreeViewFolders','s", nodePath, "')");                    
                    ScriptManager.RegisterStartupScript(this, GetType(), "message", prompt, false);                    
                }
            }

foreach循环中,我只获取“root”文件夹(位于顶部)。我如何递归地执行此操作,以获取子节点,最后找到我具有唯一node.value的节点?

我搞定了 感谢Georges Oates Larsen的回答。当用户在树视图中上传文件时,我没想到只保存节点的valuepath。所以,现在我在上传过程中将值路径保存在我的“文件”表中,并在__doPostBack

中传递该值

1 个答案:

答案 0 :(得分:1)

我不完全确定您的TreeView对象的精确程度,或者您如何存储其数据(或者甚至存储自己的数据)。但是,我确实知道一些关于树搜索算法的事情。

找到所需内容的最快方法取决于您的树是否已排序。我将假设它没有排序,这意味着解决方案将具有O(N)的最坏情况,N是树中节点的数量。

还有不同类型的树 - 我将假设您使用的是普通的旧树(任意数量的子节点,不超过一个父节点,一个根节点)。如果您提供有关正在使用的树的更多信息,我们可以提供有关如何最佳遍历它的更好信息。

鉴于这些假设,伪代码如下:

public TreeNode[] SearchTree(Tree YourTree, SearchObject SearchingFor)
{
    return SearchNode(0, YourTree.RootNode, SearchingFor);//Depth is sent in so that our recursion can keep track of how many parents the node has. This allows us to use simple arrays which are far faster than any alternative serial data storage.
}

public TreeNode[] SearchNode(int depth, TreeNode YourNode, SearchObject SearchingFor)
{
    //Edge case


    if (SearchingFor.Matches(YourNode))//Does the node match our search?
    {
        return GetHeritage(depth, YourNode);//We get the heritage at the end because it's faster than using a dynamically allocated array for every single recursion we do when only one will ever get used. That practically makes the memory used exponential! Not ot mention all of the slowdown caused by the algorithms required for reallocation.
    }


    //Recurse

    TreeNode[] ret = null;
    for (int i = 0; i < YourNode.ChildNodes.Length; i++)
    {
        //Set the ret temporary variable to our recursion, then see if it is null or not
        if ((ret = SearchNode(depth+1, YourNode.ChildNodes[i])) != null)
        {
            break;//Exit the loop!
        }
    }


    //Return the result

    return ret;//If we find the correct answer, the loop will break with ret at the correct value.
    //If, however, we do not find anything correct within this node, we will simply return null.
}



//Final calculation for the correct result.

public TreeNode[] GetHeritage(int depth, TreeNode YourNode)//This will list every node starting from the node we found going all the way back to the root node. The first element in the array returned will be the root node.
{
    TreeNode[] ret = new TreeNode[depth+1];
    ret[depth] = YourNode;//Depth is actually one less than our length, so... Hurrah!
    for (int i = depth; i >= 0; i--)
    {
        ret[depth-i] = ret[depth-(i-1)].Parent;
    }

    return ret;
}
编辑:我已经阅读了你的一些评论:

更快的方法是简单地创建一个数组,并使用“自动递增ID”的索引添加对每个节点的引用,每次向TreeView添加内容时,该指针都指向相应的节点。然后,要获取数字的路径,只需查看辅助数组中索引[number]处的节点,然后跟随其父节点到根节点! :)