2014-02-07 1 views
0

У меня есть настраиваемый элемент управления TreeView ASP.NET, который использует существующее MS Treeview. Я создаю и воссоздаю древовидную структуру при обратной передаче (она находится в UpdatePanel) из хранимого IEnumerable.StackOverflowException в рекурсивной совокупности ASP.NET treeview

Некоторые элементы добавляются следующим образом:

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

Контроль инициализируется и загружен в его OnLoad использованием BuildTreeFromItemCollection():

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

но стек вызовов выглядит уже заполнен. Где проблема?

ответ

0

Таким образом, кажется, что вся проблема была в коде генерации новых узлов в этой тестовой функции:

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

Таким образом, когда идентификатор был сгенерирован, который уже был ранее код вошел в бесконечный цикл. После расширения диапазона до (10 10000) все работает отлично.