У меня есть настраиваемый элемент управления 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);
но стек вызовов выглядит уже заполнен. Где проблема?