141 lines
3.9 KiB
C#
141 lines
3.9 KiB
C#
|
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);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|