diff --git a/WinFormSolution/Components/Exceptions/NodeIsNotLeafException.cs b/WinFormSolution/Components/Exceptions/NodeIsNotLeafException.cs
new file mode 100644
index 0000000..27f3e51
--- /dev/null
+++ b/WinFormSolution/Components/Exceptions/NodeIsNotLeafException.cs
@@ -0,0 +1,7 @@
+namespace Components.Exceptions
+{
+ public class NodeIsNotLeafException : UserControlTreeViewException
+ {
+ public NodeIsNotLeafException() : base("Selected node is not a leaf") { }
+ }
+}
diff --git a/WinFormSolution/Components/Exceptions/NotSelectedNodeException.cs b/WinFormSolution/Components/Exceptions/NotSelectedNodeException.cs
new file mode 100644
index 0000000..f9e57db
--- /dev/null
+++ b/WinFormSolution/Components/Exceptions/NotSelectedNodeException.cs
@@ -0,0 +1,7 @@
+namespace Components.Exceptions
+{
+ public class NotSelectedNodeException : UserControlTreeViewException
+ {
+ public NotSelectedNodeException() : base("Node is not selected") { }
+ }
+}
diff --git a/WinFormSolution/Components/Exceptions/PropertyNotDeclaratedException.cs b/WinFormSolution/Components/Exceptions/PropertyNotDeclaratedException.cs
new file mode 100644
index 0000000..cb04f15
--- /dev/null
+++ b/WinFormSolution/Components/Exceptions/PropertyNotDeclaratedException.cs
@@ -0,0 +1,7 @@
+namespace Components.Exceptions
+{
+ public class PropertyNotDeclaratedException : UserControlTreeViewException
+ {
+ public PropertyNotDeclaratedException(string propName) : base($"Property \"{propName}\" not declared") { }
+ }
+}
diff --git a/WinFormSolution/Components/Exceptions/PropertyNullException.cs b/WinFormSolution/Components/Exceptions/PropertyNullException.cs
new file mode 100644
index 0000000..4b664fb
--- /dev/null
+++ b/WinFormSolution/Components/Exceptions/PropertyNullException.cs
@@ -0,0 +1,7 @@
+namespace Components.Exceptions
+{
+ public class PropertyNullException : UserControlTreeViewException
+ {
+ public PropertyNullException(string propName) : base($"Property \"{propName}\" is null") { }
+ }
+}
diff --git a/WinFormSolution/Components/Exceptions/TreeHierarchyNotSetException.cs b/WinFormSolution/Components/Exceptions/TreeHierarchyNotSetException.cs
new file mode 100644
index 0000000..705d2a6
--- /dev/null
+++ b/WinFormSolution/Components/Exceptions/TreeHierarchyNotSetException.cs
@@ -0,0 +1,7 @@
+namespace Components.Exceptions
+{
+ public class TreeHierarchyNotSetException : UserControlTreeViewException
+ {
+ public TreeHierarchyNotSetException() : base("Tree hierarchy not set") { }
+ }
+}
diff --git a/WinFormSolution/Components/Exceptions/UserControlTreeViewException.cs b/WinFormSolution/Components/Exceptions/UserControlTreeViewException.cs
new file mode 100644
index 0000000..7c46527
--- /dev/null
+++ b/WinFormSolution/Components/Exceptions/UserControlTreeViewException.cs
@@ -0,0 +1,8 @@
+namespace Components.Exceptions
+{
+ public class UserControlTreeViewException : Exception
+ {
+ public UserControlTreeViewException() { }
+ public UserControlTreeViewException(string message) : base(message) { }
+ }
+}
diff --git a/WinFormSolution/Components/UserControlTreeView.Designer.cs b/WinFormSolution/Components/UserControlTreeView.Designer.cs
new file mode 100644
index 0000000..9c49b0b
--- /dev/null
+++ b/WinFormSolution/Components/UserControlTreeView.Designer.cs
@@ -0,0 +1,56 @@
+namespace Components
+{
+ partial class UserControlTreeView
+ {
+ ///
+ /// Обязательная переменная конструктора.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Освободить все используемые ресурсы.
+ ///
+ /// истинно, если управляемый ресурс должен быть удален; иначе ложно.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Код, автоматически созданный конструктором компонентов
+
+ ///
+ /// Требуемый метод для поддержки конструктора — не изменяйте
+ /// содержимое этого метода с помощью редактора кода.
+ ///
+ private void InitializeComponent()
+ {
+ treeView = new TreeView();
+ SuspendLayout();
+ //
+ // treeView
+ //
+ treeView.Location = new Point(22, 17);
+ treeView.Name = "treeView";
+ treeView.Size = new Size(188, 285);
+ treeView.TabIndex = 0;
+ //
+ // UserControlTreeView
+ //
+ AutoScaleDimensions = new SizeF(7F, 15F);
+ AutoScaleMode = AutoScaleMode.Font;
+ BackColor = SystemColors.ActiveCaption;
+ Controls.Add(treeView);
+ Name = "UserControlTreeView";
+ Size = new Size(232, 335);
+ ResumeLayout(false);
+ }
+
+ #endregion
+
+ private TreeView treeView;
+ }
+}
diff --git a/WinFormSolution/Components/UserControlTreeView.cs b/WinFormSolution/Components/UserControlTreeView.cs
new file mode 100644
index 0000000..52a3623
--- /dev/null
+++ b/WinFormSolution/Components/UserControlTreeView.cs
@@ -0,0 +1,142 @@
+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();
+ }
+ }
+}
diff --git a/WinFormSolution/Components/UserControlTreeView.resx b/WinFormSolution/Components/UserControlTreeView.resx
new file mode 100644
index 0000000..8b2ff64
--- /dev/null
+++ b/WinFormSolution/Components/UserControlTreeView.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/WinFormSolution/WinFormsApp/Employee.cs b/WinFormSolution/WinFormsApp/Employee.cs
new file mode 100644
index 0000000..b6c215f
--- /dev/null
+++ b/WinFormSolution/WinFormsApp/Employee.cs
@@ -0,0 +1,22 @@
+namespace WinFormsApp
+{
+ public class Employee
+ {
+ public string Departament { get; set; }
+ public string Position { get; set; }
+ public string Name { get; set; }
+ public string Surname { get; set; }
+ public Employee() { }
+ public Employee(string departament, string position, string surname, string name)
+ {
+ Departament = departament;
+ Position = position;
+ Name = name;
+ Surname = surname;
+ }
+ public override string ToString()
+ {
+ return Departament + ", " + Position + ", " + Surname + " " + Name;
+ }
+ }
+}
diff --git a/WinFormSolution/WinFormsApp/Form.Designer.cs b/WinFormSolution/WinFormsApp/Form.Designer.cs
index e772409..f55dc8c 100644
--- a/WinFormSolution/WinFormsApp/Form.Designer.cs
+++ b/WinFormSolution/WinFormsApp/Form.Designer.cs
@@ -31,6 +31,17 @@
userControlCheckedList = new Components.UserControlCheckedList();
buttonFillCheckedList = new Button();
buttonClearList = new Button();
+ userControlDatePicker = new Components.UserControlDatePicker();
+ dateTimePickerMinDate = new DateTimePicker();
+ dateTimePicker1 = new DateTimePicker();
+ label1 = new Label();
+ label2 = new Label();
+ userControlTreeView = new Components.UserControlTreeView();
+ buttonFillTreeView = new Button();
+ buttonClearTreeView = new Button();
+ buttonShowTreeViewNode = new Button();
+ textBoxTreeViewSelectedNodeIndex = new TextBox();
+ textBoxTreeViewSelectedObject = new TextBox();
SuspendLayout();
//
// userControlCheckedList
@@ -38,7 +49,7 @@
userControlCheckedList.BackColor = Color.Firebrick;
userControlCheckedList.Location = new Point(12, 12);
userControlCheckedList.Name = "userControlCheckedList";
- userControlCheckedList.Size = new Size(315, 170);
+ userControlCheckedList.Size = new Size(168, 170);
userControlCheckedList.TabIndex = 0;
//
// buttonFillCheckedList
@@ -61,17 +72,125 @@
buttonClearList.UseVisualStyleBackColor = true;
buttonClearList.Click += buttonClearList_Click;
//
+ // userControlDatePicker
+ //
+ userControlDatePicker.BackColor = Color.Orange;
+ userControlDatePicker.Location = new Point(273, 12);
+ userControlDatePicker.Name = "userControlDatePicker";
+ userControlDatePicker.Size = new Size(121, 50);
+ userControlDatePicker.TabIndex = 3;
+ //
+ // dateTimePickerMinDate
+ //
+ dateTimePickerMinDate.Format = DateTimePickerFormat.Short;
+ dateTimePickerMinDate.Location = new Point(246, 95);
+ dateTimePickerMinDate.Name = "dateTimePickerMinDate";
+ dateTimePickerMinDate.Size = new Size(91, 23);
+ dateTimePickerMinDate.TabIndex = 4;
+ //
+ // dateTimePicker1
+ //
+ dateTimePicker1.Format = DateTimePickerFormat.Short;
+ dateTimePicker1.Location = new Point(343, 95);
+ dateTimePicker1.Name = "dateTimePicker1";
+ dateTimePicker1.Size = new Size(95, 23);
+ dateTimePicker1.TabIndex = 5;
+ //
+ // label1
+ //
+ label1.AutoSize = true;
+ label1.Location = new Point(264, 77);
+ label1.Name = "label1";
+ label1.Size = new Size(52, 15);
+ label1.TabIndex = 6;
+ label1.Text = "MinDate";
+ //
+ // label2
+ //
+ label2.AutoSize = true;
+ label2.Location = new Point(361, 77);
+ label2.Name = "label2";
+ label2.Size = new Size(54, 15);
+ label2.TabIndex = 7;
+ label2.Text = "MaxDate";
+ //
+ // userControlTreeView
+ //
+ userControlTreeView.BackColor = SystemColors.ActiveCaption;
+ userControlTreeView.Location = new Point(498, 12);
+ userControlTreeView.Name = "userControlTreeView";
+ userControlTreeView.SelectedIndex = 0;
+ userControlTreeView.Size = new Size(232, 320);
+ userControlTreeView.TabIndex = 8;
+ //
+ // buttonFillTreeView
+ //
+ buttonFillTreeView.Location = new Point(498, 348);
+ buttonFillTreeView.Name = "buttonFillTreeView";
+ buttonFillTreeView.Size = new Size(75, 23);
+ buttonFillTreeView.TabIndex = 9;
+ buttonFillTreeView.Text = "Заполнить";
+ buttonFillTreeView.UseVisualStyleBackColor = true;
+ buttonFillTreeView.Click += buttonFillTreeView_Click;
+ //
+ // buttonClearTreeView
+ //
+ buttonClearTreeView.Location = new Point(574, 348);
+ buttonClearTreeView.Name = "buttonClearTreeView";
+ buttonClearTreeView.Size = new Size(75, 23);
+ buttonClearTreeView.TabIndex = 10;
+ buttonClearTreeView.Text = "Очистить";
+ buttonClearTreeView.UseVisualStyleBackColor = true;
+ buttonClearTreeView.Click += buttonClearTreeView_Click;
+ //
+ // buttonShowTreeViewNode
+ //
+ buttonShowTreeViewNode.Location = new Point(655, 348);
+ buttonShowTreeViewNode.Name = "buttonShowTreeViewNode";
+ buttonShowTreeViewNode.Size = new Size(75, 23);
+ buttonShowTreeViewNode.TabIndex = 11;
+ buttonShowTreeViewNode.Text = "Показать";
+ buttonShowTreeViewNode.UseVisualStyleBackColor = true;
+ buttonShowTreeViewNode.Click += buttonShowTreeViewNode_Click;
+ //
+ // textBoxTreeViewSelectedNodeIndex
+ //
+ textBoxTreeViewSelectedNodeIndex.Location = new Point(630, 397);
+ textBoxTreeViewSelectedNodeIndex.Name = "textBoxTreeViewSelectedNodeIndex";
+ textBoxTreeViewSelectedNodeIndex.Size = new Size(100, 23);
+ textBoxTreeViewSelectedNodeIndex.TabIndex = 12;
+ //
+ // textBoxTreeViewSelectedObject
+ //
+ textBoxTreeViewSelectedObject.Location = new Point(31, 397);
+ textBoxTreeViewSelectedObject.Name = "textBoxTreeViewSelectedObject";
+ textBoxTreeViewSelectedObject.ReadOnly = true;
+ textBoxTreeViewSelectedObject.Size = new Size(593, 23);
+ textBoxTreeViewSelectedObject.TabIndex = 13;
+ //
// Form
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
- ClientSize = new Size(697, 459);
+ ClientSize = new Size(768, 470);
+ Controls.Add(textBoxTreeViewSelectedObject);
+ Controls.Add(textBoxTreeViewSelectedNodeIndex);
+ Controls.Add(buttonShowTreeViewNode);
+ Controls.Add(buttonClearTreeView);
+ Controls.Add(buttonFillTreeView);
+ Controls.Add(userControlTreeView);
+ Controls.Add(label2);
+ Controls.Add(label1);
+ Controls.Add(dateTimePicker1);
+ Controls.Add(dateTimePickerMinDate);
+ Controls.Add(userControlDatePicker);
Controls.Add(buttonClearList);
Controls.Add(buttonFillCheckedList);
Controls.Add(userControlCheckedList);
Name = "Form";
Text = "Form";
ResumeLayout(false);
+ PerformLayout();
}
#endregion
@@ -79,5 +198,16 @@
private Components.UserControlCheckedList userControlCheckedList;
private Button buttonFillCheckedList;
private Button buttonClearList;
+ private Components.UserControlDatePicker userControlDatePicker;
+ private DateTimePicker dateTimePickerMinDate;
+ private DateTimePicker dateTimePicker1;
+ private Label label1;
+ private Label label2;
+ private Components.UserControlTreeView userControlTreeView;
+ private Button buttonFillTreeView;
+ private Button buttonClearTreeView;
+ private Button buttonShowTreeViewNode;
+ private TextBox textBoxTreeViewSelectedNodeIndex;
+ private TextBox textBoxTreeViewSelectedObject;
}
}
diff --git a/WinFormSolution/WinFormsApp/Form.cs b/WinFormSolution/WinFormsApp/Form.cs
index 9fa6729..0cfa343 100644
--- a/WinFormSolution/WinFormsApp/Form.cs
+++ b/WinFormSolution/WinFormsApp/Form.cs
@@ -1,3 +1,5 @@
+using Components.Exceptions;
+
namespace WinFormsApp
{
public partial class Form : System.Windows.Forms.Form
@@ -24,5 +26,65 @@ namespace WinFormsApp
{
userControlCheckedList.ClearCheckedListBoxValues();
}
+
+ private void buttonFillTreeView_Click(object sender, EventArgs e)
+ {
+ List employees = new List();
+ employees.Add(new Employee(" ", "", "", ""));
+ employees.Add(new Employee(" ", "", "", ""));
+ employees.Add(new Employee(" ", "", "", ""));
+ employees.Add(new Employee(" ", "", "", ""));
+
+ employees.Add(new Employee(" ", "", "", ""));
+ employees.Add(new Employee(" ", "", "", ""));
+ employees.Add(new Employee(" ", "", "", ""));
+ employees.Add(new Employee(" ", " ", "", ""));
+
+ employees.Add(new Employee(" ", " ", "", ""));
+ employees.Add(new Employee(" ", "PR-", "", ""));
+ employees.Add(new Employee(" ", "", "", ""));
+ employees.Add(new Employee(" ", "", "", ""));
+
+ List<(string PropertyName, bool AlwaysCreateBranch)> hierarchy = new();
+
+ hierarchy.Add(("Departament", false));
+ hierarchy.Add(("Position", false));
+ hierarchy.Add(("Surname", false));
+ hierarchy.Add(("Name", false));
+
+ userControlTreeView.SetHierarchy(hierarchy);
+
+ userControlTreeView.SetTreeObjects(employees);
+ }
+
+ private void buttonClearTreeView_Click(object sender, EventArgs e)
+ {
+ userControlTreeView.ClearTreeView();
+ }
+
+ private void buttonShowTreeViewNode_Click(object sender, EventArgs e)
+ {
+ Employee employee;
+ try
+ {
+ employee = userControlTreeView.GetObjectSelectedNode();
+ textBoxTreeViewSelectedObject.Text = employee.ToString();
+ }
+ catch (PropertyNotDeclaratedException ex)
+ {
+ MessageBox.Show(ex.Message);
+ textBoxTreeViewSelectedObject.Text = string.Empty;
+ }
+ catch (PropertyNullException ex)
+ {
+ MessageBox.Show(ex.Message);
+ textBoxTreeViewSelectedObject.Text = string.Empty;
+ }
+ catch (NotSelectedNodeException ex)
+ {
+ MessageBox.Show(ex.Message);
+ textBoxTreeViewSelectedObject.Text = string.Empty;
+ }
+ }
}
}