简体   繁体   English

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

[英]StackOverflowException in recursive ASP.NET treeview population

I have a custom ASP.NET treeview control, which uses existing MS Treeview. 我有一个自定义ASP.NET树视图控件,该控件使用现有的MS树视图。 I create and recreate the treeview upon postbacks (it is in UpdatePanel) from a stored IEnumerable. 我从存储的IEnumerable创建并重新创建树视图(在UpdatePanel中)。

Some items are added like this: 这样添加了一些项目:

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"));
}}

The control is initialized and loaded in it's OnLoad using BuildTreeFromItemCollection(): 使用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 is handled like so: 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);
    }

and this Func is temporarily attached to the NodePopulator: 并且此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;
    }

Unfortunately the BuildTreeFromItemCollection falls into infinite loop after a couple of node expansions, around 4th level, and i'm left with stack overflow. 不幸的是,在几个节点扩展之后,BuildTreeFromItemCollection陷入了无限循环,大约在第4级,并且我留下了堆栈溢出的问题。

The exact exception shows up on the line 确切的异常显示在行上

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

but the Call stack looks already filled up. 但是调用堆栈看起来已经装满了。 Where's the problem? 哪里出问题了?

So it seems that the whole problem was in the code generating new nodes in this test function: 因此,似乎整个问题出在此测试函数中生成新节点的代码中:

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

So when an ID was generated which already was earlier the code went into infinite loop. 因此,当生成一个ID时,代码早已进入无限循环。 After expanding range to (10,10000) everything works fine. 将范围扩大到(10,10000)后,一切正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM