using Components.Exceptions; using System.Reflection; namespace Components { public partial class UserControlTreeView : UserControl { public int SelectedIndex { get { return treeView.SelectedNode?.Index ?? -1; } set { if (value > -1 && value < treeView.Nodes.Count) { treeView.SelectedNode = treeView.Nodes[value]; } } } private List<(string PropertyName, bool AlwaysCreateBranch)> Hierarchy; public UserControlTreeView() { InitializeComponent(); Hierarchy = []; } public T GetObjectSelectedNode() where T : class, new() { var node = treeView.SelectedNode; if (node == null) { throw new NotSelectedNodeException(); } if ((Hierarchy?.Count ?? 0) > 0) { throw new TreeHierarchyNotSetException(); } if (node.Nodes.Count > 0) { throw new NodeIsNotLeafException(); } T obj = new T(); int propIndex = GetNodeDepth(node); while (node != null) { string propValue = node.Text; string propName = Hierarchy[propIndex].PropertyName; var prop = obj.GetType().GetProperty(propName); if (prop == null) { throw new PropertyNotDeclaratedException(propName); } prop.SetValue(obj, propValue); node = node.Parent; propIndex--; } return obj; } private int GetNodeDepth(TreeNode node) { int depth = 0; while (node.Parent != null) { depth++; node = node.Parent; } return depth; } public void SetTreeObjects(List objects) { if (objects.Count == 0) { return; } if ((Hierarchy?.Count ?? 0) > 0) { throw new TreeHierarchyNotSetException(); } PropertyInfo[]? properties = objects[0]!.GetType().GetProperties(); ClearTreeView(); foreach (T obj in objects) { var nodes = treeView.Nodes; foreach (var hierarchyProperty in Hierarchy) { PropertyInfo? objectPropertyInfo = properties?.Single(prop => prop.Name == hierarchyProperty.PropertyName); if (objectPropertyInfo == null) { throw new PropertyNotDeclaratedException(hierarchyProperty.PropertyName); } string? objectPropertyValue = objectPropertyInfo.GetValue(obj)?.ToString() ?? null; if (objectPropertyValue == null) { throw new PropertyNullException(hierarchyProperty.PropertyName); } TreeNode? node = null; if (!hierarchyProperty.AlwaysCreateBranch) { foreach (TreeNode childNode in nodes) { if (childNode.Text == objectPropertyValue) { node = childNode; break; } } } if (node == null) { node = nodes.Add(objectPropertyValue); } nodes = node.Nodes; } } } public void SetHierarchy(List<(string PropertyName, bool AlwaysCreateBranch)> hierarchy) { Hierarchy = hierarchy; } public void ClearTreeView() { treeView.Nodes.Clear(); treeView.Update(); } } }