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