From 9b7acfad636247363d4fa75aebe6d83fb148e731 Mon Sep 17 00:00:00 2001 From: "nikbel2004@outlook.com" Date: Mon, 21 Oct 2024 02:08:06 +0400 Subject: [PATCH] =?UTF-8?q?=D0=93=D0=BE=D1=82=D0=BE=D0=B2=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=BB=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82=D0=BE=D1=80=D0=BD?= =?UTF-8?q?=D0=B0=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Lab 1/Belianin_1/Belianin_1.sln | 31 ++ .../DesktopWithMyVisualComponents.csproj | 15 + .../DesktopWithMyVisualComponents/Device.cs | 28 ++ .../FormMain.Designer.cs | 380 ++++++++++++++++++ .../DesktopWithMyVisualComponents/FormMain.cs | 186 +++++++++ .../FormMain.resx | 120 ++++++ .../DesktopWithMyVisualComponents/Program.cs | 17 + .../Attributes/AlwaysCreateAttribute .cs | 13 + .../CustomInputRangeNumber.Designer.cs | 59 +++ .../CustomInputRangeNumber.cs | 122 ++++++ .../CustomInputRangeNumber.resx | 120 ++++++ ...SelectedCheckedListBoxProperty.Designer.cs | 56 +++ .../CustomSelectedCheckedListBoxProperty.cs | 89 ++++ .../CustomSelectedCheckedListBoxProperty.resx | 120 ++++++ .../CustomTreeView.Designer.cs | 55 +++ .../MyCustomComponents/CustomTreeView.cs | 175 ++++++++ .../MyCustomComponents/CustomTreeView.resx | 120 ++++++ .../Extensions/HierarchyNullException.cs | 18 + .../InvalidSelectedElementException.cs | 22 + .../Extensions/PropertyNullException.cs | 17 + .../Extensions/RangeException.cs | 20 + .../Extensions/ValueOutOfRangeException .cs | 22 + .../MyCustomComponents.csproj | 10 + 23 files changed, 1815 insertions(+) create mode 100644 Lab 1/Belianin_1/Belianin_1.sln create mode 100644 Lab 1/Belianin_1/DesktopWithMyVisualComponents/DesktopWithMyVisualComponents.csproj create mode 100644 Lab 1/Belianin_1/DesktopWithMyVisualComponents/Device.cs create mode 100644 Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.Designer.cs create mode 100644 Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.cs create mode 100644 Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.resx create mode 100644 Lab 1/Belianin_1/DesktopWithMyVisualComponents/Program.cs create mode 100644 Lab 1/Belianin_1/MyCustomComponents/Attributes/AlwaysCreateAttribute .cs create mode 100644 Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.Designer.cs create mode 100644 Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.cs create mode 100644 Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.resx create mode 100644 Lab 1/Belianin_1/MyCustomComponents/CustomSelectedCheckedListBoxProperty.Designer.cs create mode 100644 Lab 1/Belianin_1/MyCustomComponents/CustomSelectedCheckedListBoxProperty.cs create mode 100644 Lab 1/Belianin_1/MyCustomComponents/CustomSelectedCheckedListBoxProperty.resx create mode 100644 Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.Designer.cs create mode 100644 Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.cs create mode 100644 Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.resx create mode 100644 Lab 1/Belianin_1/MyCustomComponents/Extensions/HierarchyNullException.cs create mode 100644 Lab 1/Belianin_1/MyCustomComponents/Extensions/InvalidSelectedElementException.cs create mode 100644 Lab 1/Belianin_1/MyCustomComponents/Extensions/PropertyNullException.cs create mode 100644 Lab 1/Belianin_1/MyCustomComponents/Extensions/RangeException.cs create mode 100644 Lab 1/Belianin_1/MyCustomComponents/Extensions/ValueOutOfRangeException .cs create mode 100644 Lab 1/Belianin_1/MyCustomComponents/MyCustomComponents.csproj diff --git a/Lab 1/Belianin_1/Belianin_1.sln b/Lab 1/Belianin_1/Belianin_1.sln new file mode 100644 index 0000000..b133bd4 --- /dev/null +++ b/Lab 1/Belianin_1/Belianin_1.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34728.123 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyCustomComponents", "MyCustomComponents\MyCustomComponents.csproj", "{33B0240F-25C6-4577-BE81-5381D939E230}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DesktopWithMyVisualComponents", "DesktopWithMyVisualComponents\DesktopWithMyVisualComponents.csproj", "{D784BAED-C48F-46F2-A6A0-BBD6CE599A59}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {33B0240F-25C6-4577-BE81-5381D939E230}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {33B0240F-25C6-4577-BE81-5381D939E230}.Debug|Any CPU.Build.0 = Debug|Any CPU + {33B0240F-25C6-4577-BE81-5381D939E230}.Release|Any CPU.ActiveCfg = Release|Any CPU + {33B0240F-25C6-4577-BE81-5381D939E230}.Release|Any CPU.Build.0 = Release|Any CPU + {D784BAED-C48F-46F2-A6A0-BBD6CE599A59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D784BAED-C48F-46F2-A6A0-BBD6CE599A59}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D784BAED-C48F-46F2-A6A0-BBD6CE599A59}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D784BAED-C48F-46F2-A6A0-BBD6CE599A59}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {26502496-F9AE-4E02-986A-76FD9595E9AE} + EndGlobalSection +EndGlobal diff --git a/Lab 1/Belianin_1/DesktopWithMyVisualComponents/DesktopWithMyVisualComponents.csproj b/Lab 1/Belianin_1/DesktopWithMyVisualComponents/DesktopWithMyVisualComponents.csproj new file mode 100644 index 0000000..9c31612 --- /dev/null +++ b/Lab 1/Belianin_1/DesktopWithMyVisualComponents/DesktopWithMyVisualComponents.csproj @@ -0,0 +1,15 @@ + + + + WinExe + net6.0-windows + enable + true + enable + + + + + + + \ No newline at end of file diff --git a/Lab 1/Belianin_1/DesktopWithMyVisualComponents/Device.cs b/Lab 1/Belianin_1/DesktopWithMyVisualComponents/Device.cs new file mode 100644 index 0000000..0c3a0eb --- /dev/null +++ b/Lab 1/Belianin_1/DesktopWithMyVisualComponents/Device.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DesktopWithMyVisualComponents +{ + public class Device + { + public int Id { get; set; } + + public string DeviceType { get; set; } + + public string Model { get; set; } + + public string SerialNumber { get; set; } + + public Device(string serialNumber, string deviceType, string model) + { + SerialNumber = serialNumber; + Model = model; + DeviceType = deviceType; + } + + public Device() { } + } +} diff --git a/Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.Designer.cs b/Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.Designer.cs new file mode 100644 index 0000000..78a0294 --- /dev/null +++ b/Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.Designer.cs @@ -0,0 +1,380 @@ +namespace DesktopWithMyVisualComponents +{ + partial class FormMain + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + customInputRangeNumber = new MyCustomComponents.CustomInputRangeNumber(); + buttonCheck = new Button(); + labelCheckValue = new Label(); + textBoxMin = new TextBox(); + textBoxMax = new TextBox(); + buttonSetBorders = new Button(); + labelMin = new Label(); + labelMax = new Label(); + labelRange = new Label(); + groupBoxInput = new GroupBox(); + groupBoxSelected = new GroupBox(); + buttonGetSelected = new Button(); + labelSelectedValue = new Label(); + buttonClear = new Button(); + buttonAdd = new Button(); + textBoxAdd = new TextBox(); + customSelectedCheckedListBoxProperty = new MyCustomComponents.CustomSelectedCheckedListBoxProperty(); + groupBoxData = new GroupBox(); + labelDeviceType = new Label(); + labelModel = new Label(); + labelSerialNum = new Label(); + buttonGetFromTree = new Button(); + buttonAddToTree = new Button(); + comboBoxDeviceType = new ComboBox(); + textBoxModel = new TextBox(); + textBoxSerialNumber = new TextBox(); + customTreeView = new MyCustomComponents.CustomTreeView(); + groupBoxInput.SuspendLayout(); + groupBoxSelected.SuspendLayout(); + groupBoxData.SuspendLayout(); + SuspendLayout(); + // + // customInputRangeNumber + // + customInputRangeNumber.AutoValidate = AutoValidate.Disable; + customInputRangeNumber.CausesValidation = false; + customInputRangeNumber.Location = new Point(30, 19); + customInputRangeNumber.Margin = new Padding(3, 2, 3, 2); + customInputRangeNumber.MaxValue = new decimal(new int[] { -1, -1, -1, 0 }); + customInputRangeNumber.MinValue = new decimal(new int[] { -1, -1, -1, int.MinValue }); + customInputRangeNumber.Name = "customInputRangeNumber"; + customInputRangeNumber.Size = new Size(134, 30); + customInputRangeNumber.TabIndex = 0; + customInputRangeNumber.Value = new decimal(new int[] { 0, 0, 0, 0 }); + // + // buttonCheck + // + buttonCheck.Location = new Point(171, 22); + buttonCheck.Name = "buttonCheck"; + buttonCheck.Size = new Size(126, 23); + buttonCheck.TabIndex = 1; + buttonCheck.Text = "Check"; + buttonCheck.UseVisualStyleBackColor = true; + buttonCheck.Click += buttonCheck_Click; + // + // labelCheckValue + // + labelCheckValue.AutoSize = true; + labelCheckValue.Location = new Point(30, 111); + labelCheckValue.Name = "labelCheckValue"; + labelCheckValue.Size = new Size(65, 15); + labelCheckValue.TabIndex = 2; + labelCheckValue.Text = "Enter value"; + // + // textBoxMin + // + textBoxMin.Location = new Point(30, 71); + textBoxMin.Name = "textBoxMin"; + textBoxMin.Size = new Size(55, 23); + textBoxMin.TabIndex = 3; + textBoxMin.KeyPress += textBoxMin_KeyPress; + // + // textBoxMax + // + textBoxMax.Location = new Point(103, 71); + textBoxMax.Name = "textBoxMax"; + textBoxMax.Size = new Size(53, 23); + textBoxMax.TabIndex = 4; + textBoxMax.KeyPress += textBoxMax_KeyPress; + // + // buttonSetBorders + // + buttonSetBorders.Location = new Point(171, 71); + buttonSetBorders.Name = "buttonSetBorders"; + buttonSetBorders.Size = new Size(126, 23); + buttonSetBorders.TabIndex = 5; + buttonSetBorders.Text = "Set Borders"; + buttonSetBorders.UseVisualStyleBackColor = true; + buttonSetBorders.Click += buttonSetBorders_Click; + // + // labelMin + // + labelMin.AutoSize = true; + labelMin.Location = new Point(29, 54); + labelMin.Name = "labelMin"; + labelMin.Size = new Size(56, 15); + labelMin.TabIndex = 6; + labelMin.Text = "MinValue"; + // + // labelMax + // + labelMax.AutoSize = true; + labelMax.Location = new Point(101, 54); + labelMax.Name = "labelMax"; + labelMax.Size = new Size(58, 15); + labelMax.TabIndex = 7; + labelMax.Text = "MaxValue"; + // + // labelRange + // + labelRange.AutoSize = true; + labelRange.Location = new Point(88, 75); + labelRange.Name = "labelRange"; + labelRange.Size = new Size(12, 15); + labelRange.TabIndex = 8; + labelRange.Text = "-"; + // + // groupBoxInput + // + groupBoxInput.Controls.Add(customInputRangeNumber); + groupBoxInput.Controls.Add(labelCheckValue); + groupBoxInput.Controls.Add(labelRange); + groupBoxInput.Controls.Add(buttonCheck); + groupBoxInput.Controls.Add(labelMax); + groupBoxInput.Controls.Add(textBoxMin); + groupBoxInput.Controls.Add(labelMin); + groupBoxInput.Controls.Add(textBoxMax); + groupBoxInput.Controls.Add(buttonSetBorders); + groupBoxInput.Location = new Point(12, 252); + groupBoxInput.Name = "groupBoxInput"; + groupBoxInput.Size = new Size(311, 190); + groupBoxInput.TabIndex = 9; + groupBoxInput.TabStop = false; + groupBoxInput.Text = "Input"; + // + // groupBoxSelected + // + groupBoxSelected.Controls.Add(buttonGetSelected); + groupBoxSelected.Controls.Add(labelSelectedValue); + groupBoxSelected.Controls.Add(buttonClear); + groupBoxSelected.Controls.Add(buttonAdd); + groupBoxSelected.Controls.Add(textBoxAdd); + groupBoxSelected.Controls.Add(customSelectedCheckedListBoxProperty); + groupBoxSelected.Location = new Point(340, 253); + groupBoxSelected.Name = "groupBoxSelected"; + groupBoxSelected.Size = new Size(311, 190); + groupBoxSelected.TabIndex = 10; + groupBoxSelected.TabStop = false; + groupBoxSelected.Text = "Selected"; + // + // buttonGetSelected + // + buttonGetSelected.Location = new Point(192, 144); + buttonGetSelected.Name = "buttonGetSelected"; + buttonGetSelected.Size = new Size(100, 23); + buttonGetSelected.TabIndex = 14; + buttonGetSelected.Text = "Get Selected"; + buttonGetSelected.UseVisualStyleBackColor = true; + buttonGetSelected.Click += buttonGetSelected_Click; + // + // labelSelectedValue + // + labelSelectedValue.AutoSize = true; + labelSelectedValue.Location = new Point(192, 111); + labelSelectedValue.Name = "labelSelectedValue"; + labelSelectedValue.Size = new Size(82, 15); + labelSelectedValue.TabIndex = 11; + labelSelectedValue.Text = "Selected value"; + // + // buttonClear + // + buttonClear.Location = new Point(192, 81); + buttonClear.Name = "buttonClear"; + buttonClear.Size = new Size(100, 23); + buttonClear.TabIndex = 13; + buttonClear.Text = "Clear"; + buttonClear.UseVisualStyleBackColor = true; + buttonClear.Click += buttonClear_Click; + // + // buttonAdd + // + buttonAdd.Location = new Point(192, 52); + buttonAdd.Name = "buttonAdd"; + buttonAdd.Size = new Size(100, 23); + buttonAdd.TabIndex = 12; + buttonAdd.Text = "Add or Select"; + buttonAdd.UseVisualStyleBackColor = true; + buttonAdd.Click += buttonAdd_Click; + // + // textBoxAdd + // + textBoxAdd.Location = new Point(192, 23); + textBoxAdd.Name = "textBoxAdd"; + textBoxAdd.Size = new Size(100, 23); + textBoxAdd.TabIndex = 11; + // + // customSelectedCheckedListBoxProperty + // + customSelectedCheckedListBoxProperty.Location = new Point(36, 19); + customSelectedCheckedListBoxProperty.Margin = new Padding(3, 2, 3, 2); + customSelectedCheckedListBoxProperty.Name = "customSelectedCheckedListBoxProperty"; + customSelectedCheckedListBoxProperty.SelectedElement = ""; + customSelectedCheckedListBoxProperty.Size = new Size(150, 157); + customSelectedCheckedListBoxProperty.TabIndex = 0; + // + // groupBoxData + // + groupBoxData.Controls.Add(labelDeviceType); + groupBoxData.Controls.Add(labelModel); + groupBoxData.Controls.Add(labelSerialNum); + groupBoxData.Controls.Add(buttonGetFromTree); + groupBoxData.Controls.Add(buttonAddToTree); + groupBoxData.Controls.Add(comboBoxDeviceType); + groupBoxData.Controls.Add(textBoxModel); + groupBoxData.Controls.Add(textBoxSerialNumber); + groupBoxData.Controls.Add(customTreeView); + groupBoxData.Location = new Point(12, 12); + groupBoxData.Name = "groupBoxData"; + groupBoxData.Size = new Size(639, 230); + groupBoxData.TabIndex = 11; + groupBoxData.TabStop = false; + groupBoxData.Text = "Data"; + // + // labelDeviceType + // + labelDeviceType.AutoSize = true; + labelDeviceType.Location = new Point(432, 116); + labelDeviceType.Name = "labelDeviceType"; + labelDeviceType.Size = new Size(91, 15); + labelDeviceType.TabIndex = 8; + labelDeviceType.Text = "Тип устройства"; + // + // labelModel + // + labelModel.AutoSize = true; + labelModel.Location = new Point(432, 72); + labelModel.Name = "labelModel"; + labelModel.Size = new Size(50, 15); + labelModel.TabIndex = 7; + labelModel.Text = "Модель"; + // + // labelSerialNum + // + labelSerialNum.AutoSize = true; + labelSerialNum.Location = new Point(432, 28); + labelSerialNum.Name = "labelSerialNum"; + labelSerialNum.Size = new Size(105, 15); + labelSerialNum.TabIndex = 6; + labelSerialNum.Text = "Серия устройства"; + // + // buttonGetFromTree + // + buttonGetFromTree.Location = new Point(432, 195); + buttonGetFromTree.Name = "buttonGetFromTree"; + buttonGetFromTree.Size = new Size(188, 23); + buttonGetFromTree.TabIndex = 5; + buttonGetFromTree.Text = "Get Selected"; + buttonGetFromTree.UseVisualStyleBackColor = true; + buttonGetFromTree.Click += buttonGetFromTree_Click; + // + // buttonAddToTree + // + buttonAddToTree.Location = new Point(432, 166); + buttonAddToTree.Name = "buttonAddToTree"; + buttonAddToTree.Size = new Size(188, 23); + buttonAddToTree.TabIndex = 4; + buttonAddToTree.Text = "Add"; + buttonAddToTree.UseVisualStyleBackColor = true; + buttonAddToTree.Click += buttonAddToTree_Click; + // + // comboBoxDeviceType + // + comboBoxDeviceType.FormattingEnabled = true; + comboBoxDeviceType.Location = new Point(432, 134); + comboBoxDeviceType.Name = "comboBoxDeviceType"; + comboBoxDeviceType.Size = new Size(188, 23); + comboBoxDeviceType.TabIndex = 3; + // + // textBoxModel + // + textBoxModel.Location = new Point(432, 90); + textBoxModel.Name = "textBoxModel"; + textBoxModel.Size = new Size(188, 23); + textBoxModel.TabIndex = 2; + // + // textBoxSerialNumber + // + textBoxSerialNumber.Location = new Point(432, 46); + textBoxSerialNumber.Name = "textBoxSerialNumber"; + textBoxSerialNumber.Size = new Size(188, 23); + textBoxSerialNumber.TabIndex = 1; + // + // customTreeView + // + customTreeView.Location = new Point(15, 22); + customTreeView.Margin = new Padding(3, 2, 3, 2); + customTreeView.Name = "customTreeView"; + customTreeView.Size = new Size(398, 202); + customTreeView.TabIndex = 0; + // + // FormMain + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(667, 450); + Controls.Add(groupBoxData); + Controls.Add(groupBoxSelected); + Controls.Add(groupBoxInput); + Name = "FormMain"; + Text = "FormMain"; + groupBoxInput.ResumeLayout(false); + groupBoxInput.PerformLayout(); + groupBoxSelected.ResumeLayout(false); + groupBoxSelected.PerformLayout(); + groupBoxData.ResumeLayout(false); + groupBoxData.PerformLayout(); + ResumeLayout(false); + } + + #endregion + + private MyCustomComponents.CustomInputRangeNumber customInputRangeNumber; + private Button buttonCheck; + private Label labelCheckValue; + private TextBox textBoxMin; + private TextBox textBoxMax; + private Button buttonSetBorders; + private Label labelMin; + private Label labelMax; + private Label labelRange; + private GroupBox groupBoxInput; + private GroupBox groupBoxSelected; + private Button buttonGetSelected; + private Label labelSelectedValue; + private Button buttonClear; + private Button buttonAdd; + private TextBox textBoxAdd; + private MyCustomComponents.CustomSelectedCheckedListBoxProperty customSelectedCheckedListBoxProperty; + private GroupBox groupBoxData; + private MyCustomComponents.CustomTreeView customTreeView; + private Button buttonGetFromTree; + private Button buttonAddToTree; + private ComboBox comboBoxDeviceType; + private TextBox textBoxModel; + private TextBox textBoxSerialNumber; + private Label labelDeviceType; + private Label labelModel; + private Label labelSerialNum; + } +} \ No newline at end of file diff --git a/Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.cs b/Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.cs new file mode 100644 index 0000000..6df1bc8 --- /dev/null +++ b/Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.cs @@ -0,0 +1,186 @@ +using MyCustomComponents; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace DesktopWithMyVisualComponents +{ + public partial class FormMain : Form + { + readonly List devices = new() + { + new Device { Id = 1, SerialNumber = "SM-12345", DeviceType = "Мобильный телефон", Model = "IPhone 13" }, + new Device { Id = 2, SerialNumber = "SM-G3412", DeviceType = "Мобильный телефон", Model = "Samsung Galaxy S24" }, + new Device { Id = 3, SerialNumber = "CO2UD8471", DeviceType = "Ноутбук", Model = "MacBook Pro" }, + new Device { Id = 4, SerialNumber = "R80NZD8812", DeviceType = "Умные часы", Model = "Galaxy Watch 4" }, + new Device { Id = 5, SerialNumber = "FN738214", DeviceType = "Умные часы", Model = "Apple Watch 3", }, + }; + + public FormMain() + { + InitializeComponent(); + + // Пример для компонента + var list = new List() { "Значение 1", "Значение 2", "Значение 3", "Значение 4", "Значение 5" }; + customSelectedCheckedListBoxProperty.Items.AddRange(list.ToArray()); + + comboBoxDeviceType.Items.Add("Мобильный телефон"); + comboBoxDeviceType.Items.Add("Ноутбук"); + comboBoxDeviceType.Items.Add("Умные часы"); + + // Загрузка дерева с девайсами + LoadTree(); + + // Присоединить обработчик события при изменении значения + customInputRangeNumber.ChangeEvent += CustomInputRangeNumber_ChangeEvent; + } + + // Загрузка дерево с иерархией устройств на основе типа устройства, модели и серийного номера + public void LoadTree() + { + // Очистите существующие узлы перед загрузкой новых + customTreeView.Clear(); + + customTreeView.hierarchy = new List { "DeviceType", "Model", "SerialNumber" }; + + foreach (Device device in devices) + { + customTreeView.AddNode(device, "SerialNumber"); + } + } + + // Вынесенная логика проверки значения + private void UpdateLabelWithValue() + { + labelCheckValue.Text = customInputRangeNumber.Value.ToString(); + if (string.IsNullOrEmpty(labelCheckValue.Text)) + { + labelCheckValue.Text = customInputRangeNumber.Error; + } + } + + // Добавляем метод для обработки изменения значения + private void CustomInputRangeNumber_ChangeEvent(object sender, EventArgs e) + { + UpdateLabelWithValue(); + } + + // Метод проверки значения в Input + private void buttonCheck_Click(object sender, EventArgs e) + { + UpdateLabelWithValue(); + } + + // Установка границ + private void buttonSetBorders_Click(object sender, EventArgs e) + { + if (decimal.TryParse(textBoxMin.Text, out decimal minValue) && decimal.TryParse(textBoxMax.Text, out decimal maxValue)) + { + // Проверка: MaxValue должно быть больше MinValue + if (maxValue <= minValue) + { + labelCheckValue.Text = "Ошибка: MaxValue должно быть больше MinValue."; + return; + } + + // Устанавливаем границы + customInputRangeNumber.MinValue = minValue; + customInputRangeNumber.MaxValue = maxValue; + labelCheckValue.Text = "Границы установлены"; + + // Проверим текущее значение компонента на соответствие новому диапазону + /*try + { + var currentValue = customInputRangeNumber.Value; + + // Если значение в пределах, выводим сообщение об успехе + labelCheckValue.Text = "Границы установлены. Текущее значение в пределах диапазона."; + } + catch (ArgumentOutOfRangeException ex) + { + // Если текущее значение вне диапазона, выводим ошибку + labelCheckValue.Text = $"Ошибка: {ex.Message}"; + }*/ + } + else + { + labelCheckValue.Text = "Ошибка: неверные значения границ"; + } + } + + private void textBoxMin_KeyPress(object sender, KeyPressEventArgs e) + { + char ch = e.KeyChar; + + if (!Char.IsDigit(ch) && ch != 8 && ch != 45) + { + e.Handled = true; + } + } + + private void textBoxMax_KeyPress(object sender, KeyPressEventArgs e) + { + char ch = e.KeyChar; + + if (!Char.IsDigit(ch) && ch != 8 && ch != 45) + { + e.Handled = true; + } + } + + private void buttonAdd_Click(object sender, EventArgs e) + { + if (textBoxAdd.Text != "" && !customSelectedCheckedListBoxProperty.Items.Contains(textBoxAdd.Text)) + customSelectedCheckedListBoxProperty.Items.Add(textBoxAdd.Text); + else if (customSelectedCheckedListBoxProperty.Items.Contains(textBoxAdd.Text)) + customSelectedCheckedListBoxProperty.SelectedElement = textBoxAdd.Text; + } + + private void buttonClear_Click(object sender, EventArgs e) + { + customSelectedCheckedListBoxProperty.Clear(); + } + + private void buttonGetSelected_Click(object sender, EventArgs e) + { + labelSelectedValue.Text = customSelectedCheckedListBoxProperty.SelectedElement; + if (string.IsNullOrEmpty(labelSelectedValue.Text)) + { + labelSelectedValue.Text = "Значение \nне выбрано"; + } + } + + // Добавление нового узла в дерево + private void buttonAddToTree_Click(object sender, EventArgs e) + { + Device device = new Device + { + SerialNumber = textBoxSerialNumber.Text, + Model = textBoxModel.Text, + DeviceType = comboBoxDeviceType.SelectedItem?.ToString() + }; + + customTreeView.AddNode(device, "SerialNumber"); + } + + // Получение данных выбранного узла из дерева + private void buttonGetFromTree_Click(object sender, EventArgs e) + { + Device? device = customTreeView.GetSelectedNode(); + if (device == null) + { + return; + } + + textBoxSerialNumber.Text = device.SerialNumber; + textBoxModel.Text = device.Model; + comboBoxDeviceType.SelectedItem = device.DeviceType; + } + } +} diff --git a/Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.resx b/Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.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/Lab 1/Belianin_1/DesktopWithMyVisualComponents/Program.cs b/Lab 1/Belianin_1/DesktopWithMyVisualComponents/Program.cs new file mode 100644 index 0000000..7aba605 --- /dev/null +++ b/Lab 1/Belianin_1/DesktopWithMyVisualComponents/Program.cs @@ -0,0 +1,17 @@ +namespace DesktopWithMyVisualComponents +{ + internal static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + // To customize application configuration such as set high DPI settings or default font, + // see https://aka.ms/applicationconfiguration. + ApplicationConfiguration.Initialize(); + Application.Run(new FormMain()); + } + } +} \ No newline at end of file diff --git a/Lab 1/Belianin_1/MyCustomComponents/Attributes/AlwaysCreateAttribute .cs b/Lab 1/Belianin_1/MyCustomComponents/Attributes/AlwaysCreateAttribute .cs new file mode 100644 index 0000000..db0392f --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/Attributes/AlwaysCreateAttribute .cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MyCustomComponents.Attributes +{ + public class AlwaysCreateAttribute : Attribute + { + public AlwaysCreateAttribute() { } + } +} diff --git a/Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.Designer.cs b/Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.Designer.cs new file mode 100644 index 0000000..afbf042 --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.Designer.cs @@ -0,0 +1,59 @@ +namespace MyCustomComponents +{ + partial class CustomInputRangeNumber + { + /// + /// Обязательная переменная конструктора. + /// + 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() + { + numericUpDown = new NumericUpDown(); + ((System.ComponentModel.ISupportInitialize)numericUpDown).BeginInit(); + SuspendLayout(); + // + // numericUpDown + // + numericUpDown.Location = new Point(3, 2); + numericUpDown.Margin = new Padding(3, 2, 3, 2); + numericUpDown.Name = "numericUpDown"; + numericUpDown.Size = new Size(131, 23); + numericUpDown.TabIndex = 0; + // + // CustomInputRangeNumber + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + Controls.Add(numericUpDown); + Margin = new Padding(3, 2, 3, 2); + Name = "CustomInputRangeNumber"; + Size = new Size(141, 27); + ((System.ComponentModel.ISupportInitialize)numericUpDown).EndInit(); + ResumeLayout(false); + } + + #endregion + + private NumericUpDown numericUpDown; + } +} diff --git a/Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.cs b/Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.cs new file mode 100644 index 0000000..e3da2f6 --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.cs @@ -0,0 +1,122 @@ +using MyCustomComponents.Extensions; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace MyCustomComponents +{ + public partial class CustomInputRangeNumber : UserControl + { + // Диапазон + private string example = "Введите значение от " + decimal.MinValue + " до " + decimal.MaxValue; + + // В случае ошибки + public string Error { get; protected set; } = string.Empty; + + // Создам 2 публичных поля для настройки границ диапазона + public decimal? MinValue { get; set; } = null; + public decimal? MaxValue { get; set; } = null; + + + /* Публичное свойство для установки и получения введённого значения (set, get). При получении проводится проверка, + Если введённое значение не входит в диапозон, возвращать значение null, а в отдельное поле выводить текст ошибки. + При установке должна проводиться проверка, если передаваемое значение не входит в диапозон, то не заполнять поле компонента. + */ + + public decimal? Value + { + get + { + // Как мы проверим что программист не забыл задать минимальное, максимальное значение? + // Проверка, что MinValue и MaxValue задан + if (!MinValue.HasValue || !MaxValue.HasValue) + { + throw new RangeException("MinValue и MaxValue должны быть заданы."); + } + + // Проверяем, что max не может быть min + if (MaxValue.Value <= MinValue.Value) + { + throw new RangeException("MaxValue должно быть больше MinValue"); + } + + decimal currentValue = numericUpDown.Value; + + // Проверка, что значение в диапазоне + if (currentValue < MinValue.Value || currentValue > MaxValue.Value) + { + throw new RangeException($"Введённое значение {currentValue} лежит вне диапазона {MinValue.Value} - {MaxValue.Value}."); + } + + return currentValue; + } + set + { + // Проверка, что MinValue и MaxValue заданы + if (!MinValue.HasValue || !MaxValue.HasValue) + { + Error = "MinValue и MaxValue должны быть заданы."; + return; + } + + // Проверка, что MinValue меньше MaxValue + if (MinValue.Value >= MaxValue.Value) + { + Error = "Диапазон неверен. MinValue должен быть меньше, чем MaxValue."; + return; + } + + // Если число верно в диапозоне, то значение устанавливается + if (value.HasValue && value.Value >= MinValue.Value && value.Value <= MaxValue.Value) + { + numericUpDown.Value = value.Value; + + // Очистить ошибку, если значение установлено успешно + Error = null; + } + else + { + Error = $"Значение должно быть в диапазоне от {MinValue.Value} до {MaxValue.Value}."; + } + } + } + + + public CustomInputRangeNumber() + { + InitializeComponent(); + } + + private void numericUpDown_Enter(object sender, EventArgs e) + { + ToolTip toolTip = new ToolTip(); + toolTip.Show(example, numericUpDown, 30, -20, 1000); + } + + private void numericUpDown_ValueChanged(object sender, EventArgs e) + { + _changeEvent?.Invoke(sender, e); + } + + private EventHandler _changeEvent; + + // Событие, вызываемое при смене значения + public event EventHandler ChangeEvent + { + add + { + _changeEvent += value; + } + remove + { + _changeEvent -= value; + } + } + } +} diff --git a/Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.resx b/Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.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/Lab 1/Belianin_1/MyCustomComponents/CustomSelectedCheckedListBoxProperty.Designer.cs b/Lab 1/Belianin_1/MyCustomComponents/CustomSelectedCheckedListBoxProperty.Designer.cs new file mode 100644 index 0000000..ca537d7 --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/CustomSelectedCheckedListBoxProperty.Designer.cs @@ -0,0 +1,56 @@ +namespace MyCustomComponents +{ + partial class CustomSelectedCheckedListBoxProperty + { + /// + /// Обязательная переменная конструктора. + /// + 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() + { + checkedListBox = new CheckedListBox(); + SuspendLayout(); + // + // checkedListBox + // + checkedListBox.FormattingEnabled = true; + checkedListBox.Location = new Point(4, 4); + checkedListBox.Name = "checkedListBox"; + checkedListBox.Size = new Size(164, 180); + checkedListBox.TabIndex = 0; + // + // CustomSelectedCheckedListBoxProperty + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + Controls.Add(checkedListBox); + Name = "CustomSelectedCheckedListBoxProperty"; + Size = new Size(171, 209); + ResumeLayout(false); + } + + #endregion + + private CheckedListBox checkedListBox; + } +} diff --git a/Lab 1/Belianin_1/MyCustomComponents/CustomSelectedCheckedListBoxProperty.cs b/Lab 1/Belianin_1/MyCustomComponents/CustomSelectedCheckedListBoxProperty.cs new file mode 100644 index 0000000..43999dd --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/CustomSelectedCheckedListBoxProperty.cs @@ -0,0 +1,89 @@ +using MyCustomComponents.Extensions; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace MyCustomComponents +{ + public partial class CustomSelectedCheckedListBoxProperty : UserControl + { + /* Публичное свойство, которое передаёт ссылку на свойство Items + * элемента ComboBox, через которое и идёт заполнение */ + public CheckedListBox.ObjectCollection Items => checkedListBox.Items; + + public CustomSelectedCheckedListBoxProperty() + { + InitializeComponent(); + } + + // Отдельный публичный метод очистки списка + public void Clear() + { + checkedListBox.Items.Clear(); + } + + private EventHandler _changeEvent; + + private void checkedListBox_SelectedIndexChanged(object sender, EventArgs e) + { + _changeEvent?.Invoke(sender, e); + } + + // Событие, вызываемое при смене значения в CheckedListBox + public event EventHandler Changed + { + add + { + _changeEvent += value; + } + remove + { + _changeEvent -= value; + } + } + + + // Публичное свойство (set, get) для установки и получения выбранного значения (возвращает пустую строку, если нет выбранного значения) + public string SelectedElement + { + get + { + return (checkedListBox.SelectedIndex > -1 && checkedListBox.GetItemChecked(checkedListBox.SelectedIndex)) ? checkedListBox.SelectedIndex.ToString() : string.Empty; + } + set + { + if (!string.IsNullOrEmpty(value)) + { + int index = checkedListBox.Items.IndexOf(value); + + // Если попытаться установить несуществующий элемент + if (index == -1) + { + // Выбрасываем исключение, если элемент не найден в списке + throw new InvalidSelectedElementException($"Элемент '{value}' не найден в списке."); + } + + checkedListBox.SelectedItem = value; + checkedListBox.SetItemCheckState(checkedListBox.SelectedIndex, CheckState.Checked); + } + } + } + + + private void checkedListBox_ItemCheck(object sender, ItemCheckEventArgs e) + { + if (e.NewValue == CheckState.Checked && checkedListBox.CheckedItems.Count > 0) + { + checkedListBox.ItemCheck -= checkedListBox_ItemCheck; + checkedListBox.SetItemChecked(checkedListBox.CheckedIndices[0], value: false); + checkedListBox.ItemCheck += checkedListBox_ItemCheck; + } + } + } +} diff --git a/Lab 1/Belianin_1/MyCustomComponents/CustomSelectedCheckedListBoxProperty.resx b/Lab 1/Belianin_1/MyCustomComponents/CustomSelectedCheckedListBoxProperty.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/CustomSelectedCheckedListBoxProperty.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/Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.Designer.cs b/Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.Designer.cs new file mode 100644 index 0000000..35784f9 --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.Designer.cs @@ -0,0 +1,55 @@ +namespace MyCustomComponents +{ + partial class CustomTreeView + { + /// + /// Обязательная переменная конструктора. + /// + 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(3, 3); + treeView.Name = "treeView"; + treeView.Size = new Size(517, 259); + treeView.TabIndex = 0; + // + // CustomTreeCell + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + Controls.Add(treeView); + Name = "CustomTreeCell"; + Size = new Size(525, 269); + ResumeLayout(false); + } + + #endregion + + private TreeView treeView; + } +} diff --git a/Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.cs b/Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.cs new file mode 100644 index 0000000..e670360 --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.cs @@ -0,0 +1,175 @@ +using MyCustomComponents.Extensions; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using static System.Windows.Forms.VisualStyles.VisualStyleElement.Button; +using static System.Windows.Forms.VisualStyles.VisualStyleElement; +using MyCustomComponents.Attributes; +using System.Xml.Linq; + +namespace MyCustomComponents +{ + public partial class CustomTreeView : UserControl + { + public CustomTreeView() + { + InitializeComponent(); + } + + // Свойство для получения и установки выбранного узла в TreeView + public int SelectedTreeNode + { + get + { + if (treeView.SelectedNode != null) + { + return treeView.SelectedNode.Index; + } + + return -1; + } + set + { + if (treeView.Nodes.Count > 0 && value >= 0 && value < treeView.Nodes.Count) + { + treeView.SelectedNode = treeView.Nodes[value]; + } + else + { + throw new ArgumentOutOfRangeException(nameof(value), $"Индекс {value} выходит за пределы допустимого диапазона. Допустимый диапазон: от 0 до {treeView.Nodes.Count - 1}."); + } + } + } + + public List? hierarchy { get; set; } + + private Dictionary newBranch { get; set; } = new Dictionary(); + + // Отдельный публичный метод очистки всех узлов дерева + public void Clear() + { + treeView.Nodes.Clear(); + } + + // Публичный метод для получения выбранной записи из древовидной структуры + public T GetSelectedNode() where T : class, new() + { + if (hierarchy == null) + { + throw new HierarchyNullException("Hierarchy is null"); + } + + if (treeView.SelectedNode == null) + { + throw new InvalidSelectedElementException("TreeView null"); + } + + // Проверка, является ли выбранный узел корневым + if (treeView.SelectedNode.Parent == null) + { + // Выбран корневой элемент — возвращаем пустой объект + throw new InvalidSelectedElementException("Parent is null"); + } + + // Если узел выбран и существует, вызываем приватный метод для получения данных узла + return _getNode(); + } + + + // Приватный метод, идущий по узлам вверх (по иерархии) + private T _getNode() where T : new() + { + TreeNode? node = treeView.SelectedNode; + + var obj = new T(); + int level = hierarchy.Count - 1; + + // Проходим по иерархии от нижнего уровня к верхнему + while (node != null && level >= 0) + { + var property = hierarchy[level]; + obj.GetType().GetProperty(property)?.SetValue(obj, node.Text); + + node = node.Parent; + + level--; + } + + return obj; + } + + /* Параметризированный метод, у которого в передаваемых параметрах + * идёт объект какого-то класса и имя свойства/поля, до которого согласно + * иерархии будет следовать формирование ветви + */ + public void AddNode(T obj, string propertyName) + { + if (hierarchy == null) + { + throw new HierarchyNullException("Hierarchy is null"); + } + + if (obj == null) + { + throw new ArgumentNullException("Added object is null"); + } + + // Ищем индекс свойства в иерархии + int index = hierarchy.IndexOf(propertyName); + if (index == -1) + { + throw new PropertyNullException("Property not found in hierarchy"); + } + + // Получаем первый узел в дереве, либо нулл, если узлов нет + TreeNode currentNode = treeView.SelectedNode; + + // Проходимся по иерархии + foreach (var property in hierarchy) + { + // Получаем значение свойства + var value = obj.GetType().GetProperty(property)?.GetValue(obj, null)?.ToString(); + bool createNewBranch = newBranch != null && newBranch.ContainsKey(propertyName) && newBranch[propertyName]; + + if (currentNode == null) + { + currentNode = treeView.Nodes.Cast() + .FirstOrDefault(n => n.Text == value) ?? treeView.Nodes.Add(value); + } + else + { + var childNode = currentNode.Nodes.Cast().FirstOrDefault(n => n.Text == value); + + // Проверка нужно ли нам создавать дочерний узел + if (childNode == null || createNewBranch) + { + childNode = currentNode.Nodes.Add(value); + } + + // Переходим на уровень этого дочернего узла + currentNode = childNode; + } + + if (property == propertyName) + { + break; + } + + } + } + + + public void SetHierarchy(List hierarchy, Dictionary newBranch) + { + this.hierarchy = hierarchy; + this.newBranch = newBranch; + } + } +} diff --git a/Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.resx b/Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.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/Lab 1/Belianin_1/MyCustomComponents/Extensions/HierarchyNullException.cs b/Lab 1/Belianin_1/MyCustomComponents/Extensions/HierarchyNullException.cs new file mode 100644 index 0000000..1699429 --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/Extensions/HierarchyNullException.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MyCustomComponents.Extensions +{ + public class HierarchyNullException : Exception + { + public HierarchyNullException() { } + + public HierarchyNullException(string message) : base(message) { } + + public HierarchyNullException(string message, Exception inner) : base(message, inner) { } + + } +} diff --git a/Lab 1/Belianin_1/MyCustomComponents/Extensions/InvalidSelectedElementException.cs b/Lab 1/Belianin_1/MyCustomComponents/Extensions/InvalidSelectedElementException.cs new file mode 100644 index 0000000..f5b0986 --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/Extensions/InvalidSelectedElementException.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MyCustomComponents.Extensions +{ + // Исключение, если нет выбранного и отмеченного элемента + public class InvalidSelectedElementException : Exception + { + public InvalidSelectedElementException() { } + + public InvalidSelectedElementException(string message) : base(message) + { + } + + public InvalidSelectedElementException(string message, Exception inner) : base(message, inner) + { + } + } +} diff --git a/Lab 1/Belianin_1/MyCustomComponents/Extensions/PropertyNullException.cs b/Lab 1/Belianin_1/MyCustomComponents/Extensions/PropertyNullException.cs new file mode 100644 index 0000000..0de8cea --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/Extensions/PropertyNullException.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MyCustomComponents.Extensions +{ + public class PropertyNullException : Exception + { + public PropertyNullException() { } + + public PropertyNullException(string message) : base(message) { } + + public PropertyNullException(string message, Exception inner) : base(message, inner) { } + } +} diff --git a/Lab 1/Belianin_1/MyCustomComponents/Extensions/RangeException.cs b/Lab 1/Belianin_1/MyCustomComponents/Extensions/RangeException.cs new file mode 100644 index 0000000..aa8e00c --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/Extensions/RangeException.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MyCustomComponents.Extensions +{ + internal class RangeException : Exception + { + public RangeException() { } + + public RangeException(string message) : base(message) + { } + + public RangeException(string message, Exception inner) : base(message, inner) + { + } + } +} diff --git a/Lab 1/Belianin_1/MyCustomComponents/Extensions/ValueOutOfRangeException .cs b/Lab 1/Belianin_1/MyCustomComponents/Extensions/ValueOutOfRangeException .cs new file mode 100644 index 0000000..91e3b33 --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/Extensions/ValueOutOfRangeException .cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MyCustomComponents.Extensions +{ + // Ошибка неверного значения, когда значение выходит за границы диапазона + public class ValueOutOfRangeException : Exception + { + public ValueOutOfRangeException() { } + + public ValueOutOfRangeException(string message) : base(message) + { + } + + public ValueOutOfRangeException(string message, Exception inner) : base(message, inner) + { + } + } +} diff --git a/Lab 1/Belianin_1/MyCustomComponents/MyCustomComponents.csproj b/Lab 1/Belianin_1/MyCustomComponents/MyCustomComponents.csproj new file mode 100644 index 0000000..060aa1c --- /dev/null +++ b/Lab 1/Belianin_1/MyCustomComponents/MyCustomComponents.csproj @@ -0,0 +1,10 @@ + + + + net6.0-windows + enable + true + enable + + +