дерево

This commit is contained in:
annalyovushkina@yandex.ru 2024-09-23 12:06:31 +04:00
parent 1f8701e03c
commit d0b096e308
3 changed files with 58 additions and 82 deletions

View File

@ -15,106 +15,81 @@ namespace KOP_Labs
{
public partial class CustomTree : UserControl
{
private List<string> hierarchy;
public CustomTree()
{
InitializeComponent();
}
public List<string>? Hierarcy { get; set; }
public void Clear()
{
treeView.Nodes.Clear();
hierarchy = new List<string>();
}
public void AddNode<T>(T obj) {
if (Hierarcy == null)
{
throw new HierarcyNullException("Иерархия не задана");
}
if (obj == null)
{
throw new ArgumentNullException("Объект не найден");
}
var values = GetValuesVithStructure(obj);
var treeNode = new TreeNode();
AddNodesToTreeNode(treeView.Nodes, treeNode.Nodes);
var nodes = AddElementsToParent(values, treeNode);
treeView.Nodes.Clear();
AddNodesToTreeNode(nodes.Nodes, treeView.Nodes);
}
private void AddNodesToTreeNode(TreeNodeCollection fromNodeCollection, TreeNodeCollection toNodeCollection)
public void SetHierarcy(List<string> hierarchy)
{
for (int i = 0; i < fromNodeCollection.Count; i++)
{
var node = fromNodeCollection[i].Clone() as TreeNode;
toNodeCollection.Add(node);
}
this.hierarchy = hierarchy;
}
private Dictionary<string, (object, bool)> GetValuesVithStructure<T>(T obj)
public int SelectedNodeIndex
{
PropertyInfo[]? properties = obj?.GetType().GetProperties();
var dict = new Dictionary<string, (object, bool)>();
foreach (var elem in Hierarcy!) {
PropertyInfo? prop = properties?.Single(prop => prop.Name == elem);
if (prop == null)
get
{
return treeView.SelectedNode?.Index ?? -1;
}
set
{
if (value >= 0 && value < treeView.Nodes.Count)
{
throw new PropertyNullException(nameof(prop));
treeView.SelectedNode = treeView.Nodes[value];
}
var atr = prop.GetCustomAttributes()?.SingleOrDefault(atr => atr is AlwaysCreateAttribute);
dict[elem] = (prop.GetValue(obj)!, atr == null ? false : true);
}
return dict;
}
private TreeNode AddElementsToParent(Dictionary<string, (object, bool)> elements, TreeNode parent)
{
if (elements.Count == 0)
{
return parent;
}
var firstElem = elements.First();
var child = parent.Nodes
.Cast<TreeNode>()
.SingleOrDefault(node => node.Text == (string)firstElem.Value.Item1);
if (child != null && !firstElem.Value.Item2)
{
elements.Remove(firstElem.Key);
return AddElementsToParent(elements, child).Parent;
}
else
{
var newChild = new TreeNode(firstElem.Value.Item1?.ToString() ?? string.Empty);
newChild.Tag = new Tuple<string, object>(firstElem.Key, firstElem.Value.Item1!);
elements.Remove(firstElem.Key);
parent.Nodes.Add(AddElementsToParent(elements, newChild));
return parent;
}
}
public T GetSelectedNode<T>()
where T : new()
public void AddObjectToTree<T>(T obj)
{
if (Hierarcy == null)
TreeNode currentNode = treeView.Nodes.Count > 0 ? treeView.Nodes[0] : treeView.Nodes.Add("");
foreach (var property in hierarchy)
{
throw new HierarcyNullException("Иерархия не задана");
var value = obj.GetType().GetProperty(property).GetValue(obj, null).ToString();
var childNode = currentNode.Nodes.Cast<TreeNode>().FirstOrDefault(n => n.Text == value);
if (childNode == null)
{
childNode = currentNode.Nodes.Add(value);
}
currentNode = childNode;
}
}
public T GetSelectedObject<T>() where T : new()
{
if (treeView.SelectedNode == null)
{
return new T();
throw new InvalidOperationException("Узел не выбран");
}
return GetNode(new T(), treeView.SelectedNode);
}
private T GetNode<T>(T obj, TreeNode node)
{
if (node != null && node.Tag != null)
var node = treeView.SelectedNode;
if (node.Nodes.Count != 0)
{
var tag = node.Tag as Tuple<string, object>;
throw new InvalidOperationException("Узел не конечный, сформировать объект нельзя");
}
var property = obj?.GetType().GetProperty(tag!.Item1);
property?.SetValue(obj, Convert.ChangeType(tag!.Item2, property.PropertyType));
var obj = new T();
foreach (var property in hierarchy)
{
var value = node.Text;
var propInfo = typeof(T).GetProperty(property);
if (propInfo == null)
{
throw new InvalidOperationException($"Свойство {property} не найдено в классе {typeof(T).Name}");
}
propInfo.SetValue(obj, Convert.ChangeType(value, propInfo.PropertyType));
GetNode(obj, node.Parent);
node = node.Parent;
if (node == null)
{
break;
}
}
return obj;
}

View File

@ -59,7 +59,7 @@
//
// customTree1
//
customTree1.Hierarcy = null;
//customTree1.Hierarcy = null;
customTree1.Location = new Point(615, 50);
customTree1.Name = "customTree1";
customTree1.Size = new Size(309, 384);

View File

@ -28,10 +28,11 @@ namespace WinFormForTest
public void LoadTree()
{
customTree1.Hierarcy = new List<string> { "Type", "Name", "Color" };
var hierarcy= new List<string> { "Type", "Name", "Color" };
customTree1.SetHierarcy(hierarcy);
foreach (Plant plant in plants)
{
customTree1.AddNode(plant);
customTree1.AddObjectToTree(plant);
}
}
private void buttonClear_Click(object sender, EventArgs e)