namespace CustomsComponentsVar2; public partial class CustomTreeView: UserControl { /// /// Иерархия дерева по полям класса /// private List hierarchy; /// /// Список полей, для которых обязательно создаем новыую ветку (например, ФИО, на случай полных однофамильцев) /// private Dictionary newBranch; public int SelectedIndex { get { return SelectedIndex; } set { SelectedIndex = value; } } public CustomTreeView() { InitializeComponent(); hierarchy = new List(); } /// /// Устанавливает иерархию по полям класса, начиная с главного /// /// /// public void setHierarchy(List hierarchy, Dictionary newBranch) { this.hierarchy = hierarchy; this.newBranch = newBranch; } /// /// Строит дерево на основе полученных элементов /// /// /// public void build(List elements) { foreach (var el in elements) { add(el, hierarchy, treeView.Nodes, 0); } } /// /// Рекурсивно добавляет узлы в дерево /// /// /// /// /// /// private void add(T el, List hierarchy, TreeNodeCollection nodes, int level) { // если превышено количество уровней в иерархии if (level >= hierarchy.Count) { return; } // находим свойство (на основе иерархии) – извлекаем значение string property = hierarchy[level]; string propertyValue = el.GetType().GetProperty(property)?.GetValue(el)?.ToString() ?? string.Empty; // ищем, есть ли уже узел с таким названием TreeNode foundNode = null; foreach (TreeNode node in nodes) { if (node.Text == propertyValue) { foundNode = node; break; } } // если не найден ИЛИ указано, что нужно создать новый узел, то добавляем новый узел if (foundNode == null || newBranch.ContainsKey(property) && newBranch[property]) { foundNode = nodes.Add(propertyValue); } // шаг на уровень глубже add(el, hierarchy, foundNode.Nodes, level + 1); } /// /// получение выбранного элемента по индексу (с рефлексией) /// /// /// public T getSelected() where T : new() { if (SelectedIndex >= 0 && SelectedIndex < treeView.Nodes.Count) { TreeNode node = treeView.Nodes[SelectedIndex]; // если последний уровень if (node.Level == hierarchy.Count) { T el = new T(); setProperties(el, node, node.Level); return el; } } return default(T); } /// /// получение значений свойств элемента по узлам /// /// /// /// /// private void setProperties(T el, TreeNode node, int level) { if (hierarchy.Count >= level) { var property = hierarchy[level]; var propertyValue = typeof(T).GetProperty(property); if (propertyValue != null) { propertyValue.SetValue(el, node.Text); } } if (node.Parent != null) { setProperties(el, node.Parent, level - 1); } } }