Почему предикат неверно интерпретирует значения параметров при вызове рекурсивной функции
Я пытаюсь создать расширенный элемент управления treeview, наследующий существующий элемент управления winform TreeView. Создал а
Load()
функция в классе TreeViewEx. В этой функции источник данных зацикливается в foreach. Этот foreach затем вызывает Where()
метод расширения на циклическом источнике данных, передающий ему метод Methode (который принимает в качестве параметра текущий элемент), возвращающий предикат. Этот предикат неверно интерпретирует переданное ему значение параметра. Похоже, он использует предыдущие значения параметров.значение arg в методе перед возвращением предиката => Изображение[^]
значение arg, когда отладчик вводит предикат => Изображение[^]
Что я уже пробовал:
Изначально я думал, что такое поведение связано с тем, что я перебираю перечисляемый, а не список, поэтому я меняю различные перечисляемые объекты на список, но ничего не изменилось. Также попытался установить возвращаемый предикат, но ничего не получилось.
Функция нагрузки :
public Func<T, Func<T, bool>> GetChildrenPredicate { get; set; } . . . public virtual void Load(List<T> dataSource = null) { try { if (CreateNode == null) { OnError?.Invoke(this, new ArgumentNullException("CreateNode")); return; } if (GetParentKey == null) { OnError?.Invoke(this, new ArgumentNullException("GetParentKey")); return; } if (GetChildrenPredicate == null) { OnError?.Invoke(this, new ArgumentNullException("GetChildrenPredicate")); return; } var finalDataSource = dataSource ?? DataSource; TreeNode node = null; BeginUpdate(); foreach (var item in finalDataSource) { node = CreateNode(item); node.Tag = item; if (this.Nodes.Find(node.Name, true).Count() == 0) { var n = this.Nodes.Find(this.GetParentKey(item), true).FirstOrDefault() as TreeNode; if (n == null) { this.Nodes.Add(node); } else { n.Nodes.Add(node); } List<T> children = finalDataSource .ToList() .Where(this.GetChildrenPredicate(item)) .ToList(); //this.GetChildrenPredicate is //the property func generating the //predicate set by a different class if (children.Count() > 0) { // Recursively call this function for all childRows Load(children); } } } EndUpdate(); } catch (Exception ex) { OnError?.Invoke(this, ex); } }
GetChildrenPredicate :
private Func<ORM.DataModels.Menu, bool> GetChildrenPredicate(ORM.DataModels.Menu arg) { return (ORM.DataModels.Menu m) => (m.Lepere == arg.Codmen) || (m.Lepere == null && arg.Codmen == "_" + m.Niveau); }
Gerry Schmitz
Я создаю свои собственные пользовательские древовидные представления (WPF, UWP), используя отсортированный список элементов, listview, level # и около 30 строк разнесенного кода.
Я бы сказал, что ваш чересчур спроектирован; предполагая, что он когда-либо работает и может быть поддержан.
bugMaker-237
Мой treeview находится в winform и является универсальным. Таким образом, он полагается на методы exteranl и события, установленные контроллером. Если вы считаете, что это можно улучшить, я готов выслушать любое предложение.