PIbd-32_Isaeva_A.I._COP_2/CustomTreeView.cs

141 lines
3.9 KiB
C#
Raw Permalink Normal View History

namespace CustomsComponentsVar2;
public partial class CustomTreeView: UserControl
{
/// <summary>
/// Иерархия дерева по полям класса
/// </summary>
private List<string> hierarchy;
/// <summary>
/// Список полей, для которых обязательно создаем новыую ветку (например, ФИО, на случай полных однофамильцев)
/// </summary>
private Dictionary<string, bool> newBranch;
public int SelectedIndex
{
get
{
return SelectedIndex;
}
set
{
SelectedIndex = value;
}
}
public CustomTreeView()
{
InitializeComponent();
hierarchy = new List<string>();
}
/// <summary>
/// Устанавливает иерархию по полям класса, начиная с главного
/// </summary>
/// <param name="hierarchy"></param>
/// <param name="newBranch"></param>
public void setHierarchy(List<string> hierarchy, Dictionary<string, bool> newBranch)
{
this.hierarchy = hierarchy;
this.newBranch = newBranch;
}
/// <summary>
/// Строит дерево на основе полученных элементов
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="elements"></param>
public void build<T>(List<T> elements)
{
foreach (var el in elements)
{
add(el, hierarchy, treeView.Nodes, 0);
}
}
/// <summary>
/// Рекурсивно добавляет узлы в дерево
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="el"></param>
/// <param name="hierarchy"></param>
/// <param name="nodes"></param>
/// <param name="level"></param>
private void add<T>(T el, List<string> 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);
}
/// <summary>
/// получение выбранного элемента по индексу (с рефлексией)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T getSelected<T>() 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);
}
/// <summary>
/// получение значений свойств элемента по узлам
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="el"></param>
/// <param name="node"></param>
/// <param name="level"></param>
private void setProperties<T>(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);
}
}
}