Готовая лабораторная работа 1
This commit is contained in:
parent
5c94bfc598
commit
9b7acfad63
31
Lab 1/Belianin_1/Belianin_1.sln
Normal file
31
Lab 1/Belianin_1/Belianin_1.sln
Normal file
@ -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
|
@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\MyCustomComponents\MyCustomComponents.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
28
Lab 1/Belianin_1/DesktopWithMyVisualComponents/Device.cs
Normal file
28
Lab 1/Belianin_1/DesktopWithMyVisualComponents/Device.cs
Normal file
@ -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() { }
|
||||||
|
}
|
||||||
|
}
|
380
Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.Designer.cs
generated
Normal file
380
Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.Designer.cs
generated
Normal file
@ -0,0 +1,380 @@
|
|||||||
|
namespace DesktopWithMyVisualComponents
|
||||||
|
{
|
||||||
|
partial class FormMain
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
186
Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.cs
Normal file
186
Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.cs
Normal file
@ -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<Device> 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<string>() { "Значение 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<string> { "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<Device>();
|
||||||
|
if (device == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
textBoxSerialNumber.Text = device.SerialNumber;
|
||||||
|
textBoxModel.Text = device.Model;
|
||||||
|
comboBoxDeviceType.SelectedItem = device.DeviceType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.resx
Normal file
120
Lab 1/Belianin_1/DesktopWithMyVisualComponents/FormMain.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
17
Lab 1/Belianin_1/DesktopWithMyVisualComponents/Program.cs
Normal file
17
Lab 1/Belianin_1/DesktopWithMyVisualComponents/Program.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace DesktopWithMyVisualComponents
|
||||||
|
{
|
||||||
|
internal static class Program
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The main entry point for the application.
|
||||||
|
/// </summary>
|
||||||
|
[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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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() { }
|
||||||
|
}
|
||||||
|
}
|
59
Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.Designer.cs
generated
Normal file
59
Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.Designer.cs
generated
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
namespace MyCustomComponents
|
||||||
|
{
|
||||||
|
partial class CustomInputRangeNumber
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Обязательная переменная конструктора.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Освободить все используемые ресурсы.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Код, автоматически созданный конструктором компонентов
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Требуемый метод для поддержки конструктора — не изменяйте
|
||||||
|
/// содержимое этого метода с помощью редактора кода.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
122
Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.cs
Normal file
122
Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.cs
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.resx
Normal file
120
Lab 1/Belianin_1/MyCustomComponents/CustomInputRangeNumber.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
56
Lab 1/Belianin_1/MyCustomComponents/CustomSelectedCheckedListBoxProperty.Designer.cs
generated
Normal file
56
Lab 1/Belianin_1/MyCustomComponents/CustomSelectedCheckedListBoxProperty.Designer.cs
generated
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
namespace MyCustomComponents
|
||||||
|
{
|
||||||
|
partial class CustomSelectedCheckedListBoxProperty
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Обязательная переменная конструктора.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Освободить все используемые ресурсы.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Код, автоматически созданный конструктором компонентов
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Требуемый метод для поддержки конструктора — не изменяйте
|
||||||
|
/// содержимое этого метода с помощью редактора кода.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
55
Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.Designer.cs
generated
Normal file
55
Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.Designer.cs
generated
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
namespace MyCustomComponents
|
||||||
|
{
|
||||||
|
partial class CustomTreeView
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Обязательная переменная конструктора.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Освободить все используемые ресурсы.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Код, автоматически созданный конструктором компонентов
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Требуемый метод для поддержки конструктора — не изменяйте
|
||||||
|
/// содержимое этого метода с помощью редактора кода.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
175
Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.cs
Normal file
175
Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.cs
Normal file
@ -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<string>? hierarchy { get; set; }
|
||||||
|
|
||||||
|
private Dictionary<string, bool> newBranch { get; set; } = new Dictionary<string, bool>();
|
||||||
|
|
||||||
|
// Отдельный публичный метод очистки всех узлов дерева
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
treeView.Nodes.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Публичный метод для получения выбранной записи из древовидной структуры
|
||||||
|
public T GetSelectedNode<T>() 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<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Приватный метод, идущий по узлам вверх (по иерархии)
|
||||||
|
private T _getNode<T>() 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>(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<TreeNode>()
|
||||||
|
.FirstOrDefault(n => n.Text == value) ?? treeView.Nodes.Add(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var childNode = currentNode.Nodes.Cast<TreeNode>().FirstOrDefault(n => n.Text == value);
|
||||||
|
|
||||||
|
// Проверка нужно ли нам создавать дочерний узел
|
||||||
|
if (childNode == null || createNewBranch)
|
||||||
|
{
|
||||||
|
childNode = currentNode.Nodes.Add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Переходим на уровень этого дочернего узла
|
||||||
|
currentNode = childNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (property == propertyName)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SetHierarchy(List<string> hierarchy, Dictionary<string, bool> newBranch)
|
||||||
|
{
|
||||||
|
this.hierarchy = hierarchy;
|
||||||
|
this.newBranch = newBranch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.resx
Normal file
120
Lab 1/Belianin_1/MyCustomComponents/CustomTreeView.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
@ -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) { }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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) { }
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
Loading…
Reference in New Issue
Block a user