递归ASP.NET树视图填充中的StackOverflowException

时间:2014-02-07 14:14:43

标签: c# asp.net webforms

我有一个自定义的ASP.NET树视图控件,它使用现有的MS Treeview。我从存储的IEnumerable创建并重新创建了回溯(它在UpdatePanel中)的树视图。

有些项目添加如下:

protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack && !Page.IsAsync)
        {
            DD.Items = null;

            DD.Items.Add(new TreeviewItem("Choice 1", "4", "-1"));// = items;
            DD.Items.Add(new TreeviewItem("something", "1", "-1"));
            DD.Items.Add(new TreeviewItem("Europe", "2", "-1"));
            DD.Items.Add(new TreeviewItem("pff", "3", "-1"));
}}

使用BuildTreeFromItemCollection()初始化控件并将其加载到OnLoad中:

    public void BuildTreeFromItemCollection()
    {
        BuildTreeFromItemCollection(this.Items, null);
    }

    public void BuildTreeFromItemCollection(IEnumerable<StoredItem> items, TreeNode parentNode)
    {

        IEnumerable<TreeviewItem> tvItems = items.Cast<TreeviewItem>();
        var nodes = tvItems.Where(x => parentNode == null ? int.Parse(x.Parent) <= 0 : x.Parent == parentNode.Value);

        TreeNode childNode;
        foreach (var i in nodes)
        {
            childNode = new TreeNode(i.Name, i.Value)
            {
                PopulateOnDemand = this.PopulateOnDemand
            };

            if (parentNode == null)
            {
                TvHierarchy.Nodes.Add(childNode);
            }
            else
            {
                parentNode.ChildNodes.Add(childNode);
            }

            this.BuildTreeFromItemCollection(items, childNode);
        } 
    }

TreeNodePopulate的处理方式如下:

    void TvHierarchy_TreeNodePopulate(object sender, TreeNodeEventArgs e)
    {

        this.EnsureChildControls();

        IEnumerable<StoredItem> childItems = NodePopulator(e.Node.Value);
        foreach (StoredItem item in childItems)
        {
            TreeNode newNode = new TreeNode(item.Name, item.Value);
            newNode.PopulateOnDemand = this.PopulateOnDemand;
            e.Node.ChildNodes.Add(newNode);
        }

        this.Items.AddRange(childItems);
    }

并且此Func暂时附加到NodePopulator:

    private IEnumerable<StoredItem> ItemLoader(string val)
    {
        List<StoredItem> itemList = new List<StoredItem>();
        Random r = new Random();

        for (int i = 0; i <= 4; i++)
        {
            int rand = r.Next(10,100);
            itemList.Add(new TreeviewItem("test " + rand.ToString(), rand.ToString(), val));
        }

        return itemList;
    }

不幸的是,BuildTreeFromItemCollection在几个节点扩展后进入无限循环,大约在第4级,并且我留下了堆栈溢出。

确切的例外显示在

行上
var nodes = tvItems.Where(x => parentNode == null ? int.Parse(x.Parent) <= 0 : x.Parent == parentNode.Value);

但是调用堆栈看起来已经填满了。问题出在哪里?

1 个答案:

答案 0 :(得分:0)

因此,似乎整个问题出现在代码中,在此测试函数中生成新节点:

int rand = r.Next(10,100);
itemList.Add(new TreeviewItem("test " + rand.ToString(), rand.ToString(), val));

因此,当生成一个已经更早的ID时,代码进入无限循环。将范围扩大到(10,10000)之后一切正常。