Compare commits
2 Commits
main
...
laboratory
Author | SHA1 | Date | |
---|---|---|---|
|
de54e31c8b | ||
|
0247578e56 |
31
Lab 2/Belianin_2/Belianin_2.sln
Normal file
31
Lab 2/Belianin_2/Belianin_2.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,21 @@
|
||||
<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>
|
||||
<PackageReference Include="DocumentFormat.OpenXml" Version="2.20.0" />
|
||||
<PackageReference Include="Microsoft.Win32.SystemEvents" Version="7.0.0" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MyCustomComponents\MyCustomComponents.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
40
Lab 2/Belianin_2/DesktopWithMyVisualComponents/Device.cs
Normal file
40
Lab 2/Belianin_2/DesktopWithMyVisualComponents/Device.cs
Normal file
@ -0,0 +1,40 @@
|
||||
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 string Owner { get; set; }
|
||||
|
||||
public DateTime PurchaseDate { get; set; }
|
||||
|
||||
public string State { get; set; }
|
||||
|
||||
public string Color { get; set; }
|
||||
|
||||
public int WarrantyPeriod { get; set; }
|
||||
|
||||
public int Price { get; set; }
|
||||
|
||||
public Device(string serialNumber, string deviceType, string model)
|
||||
{
|
||||
SerialNumber = serialNumber;
|
||||
Model = model;
|
||||
DeviceType = deviceType;
|
||||
}
|
||||
|
||||
public Device() { }
|
||||
}
|
||||
}
|
424
Lab 2/Belianin_2/DesktopWithMyVisualComponents/FormMain.Designer.cs
generated
Normal file
424
Lab 2/Belianin_2/DesktopWithMyVisualComponents/FormMain.Designer.cs
generated
Normal file
@ -0,0 +1,424 @@
|
||||
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()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.customInputRangeNumber = new MyCustomComponents.CustomInputRangeNumber();
|
||||
this.buttonCheck = new System.Windows.Forms.Button();
|
||||
this.labelCheckValue = new System.Windows.Forms.Label();
|
||||
this.groupBoxInput = new System.Windows.Forms.GroupBox();
|
||||
this.groupBoxSelected = new System.Windows.Forms.GroupBox();
|
||||
this.buttonGetSelected = new System.Windows.Forms.Button();
|
||||
this.labelSelectedValue = new System.Windows.Forms.Label();
|
||||
this.buttonClear = new System.Windows.Forms.Button();
|
||||
this.buttonAdd = new System.Windows.Forms.Button();
|
||||
this.textBoxAdd = new System.Windows.Forms.TextBox();
|
||||
this.customSelectedCheckedListBoxProperty = new MyCustomComponents.CustomSelectedCheckedListBoxProperty();
|
||||
this.groupBoxData = new System.Windows.Forms.GroupBox();
|
||||
this.labelDeviceType = new System.Windows.Forms.Label();
|
||||
this.labelModel = new System.Windows.Forms.Label();
|
||||
this.labelRegNum = new System.Windows.Forms.Label();
|
||||
this.buttonGetFromTree = new System.Windows.Forms.Button();
|
||||
this.buttonAddToTree = new System.Windows.Forms.Button();
|
||||
this.comboBoxDeviceType = new System.Windows.Forms.ComboBox();
|
||||
this.textBoxModel = new System.Windows.Forms.TextBox();
|
||||
this.textBoxSerialNumber = new System.Windows.Forms.TextBox();
|
||||
this.customTreeView = new MyCustomComponents.CustomTreeView();
|
||||
this.tabControl = new System.Windows.Forms.TabControl();
|
||||
this.Visual = new System.Windows.Forms.TabPage();
|
||||
this.Docs = new System.Windows.Forms.TabPage();
|
||||
this.buttonWordWithDiagram = new System.Windows.Forms.Button();
|
||||
this.buttonWordWithTable = new System.Windows.Forms.Button();
|
||||
this.buttonWordWithImage = new System.Windows.Forms.Button();
|
||||
this.wordWithImages = new MyCustomComponents.WordWithImages(this.components);
|
||||
this.wordWithTable = new MyCustomComponents.WordWithTable(this.components);
|
||||
this.wordWithDiagram = new MyCustomComponents.WordWithDiagram(this.components);
|
||||
this.groupBoxInput.SuspendLayout();
|
||||
this.groupBoxSelected.SuspendLayout();
|
||||
this.groupBoxData.SuspendLayout();
|
||||
this.tabControl.SuspendLayout();
|
||||
this.Visual.SuspendLayout();
|
||||
this.Docs.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// customInputRangeNumber
|
||||
//
|
||||
this.customInputRangeNumber.AutoValidate = System.Windows.Forms.AutoValidate.Disable;
|
||||
this.customInputRangeNumber.CausesValidation = false;
|
||||
this.customInputRangeNumber.Location = new System.Drawing.Point(34, 25);
|
||||
this.customInputRangeNumber.Margin = new System.Windows.Forms.Padding(3, 5, 3, 5);
|
||||
this.customInputRangeNumber.MaxValue = new decimal(new int[] { -1, -1, -1, 0});
|
||||
this.customInputRangeNumber.MinValue = new decimal(new int[] { -1, -1, -1, -2147483648});
|
||||
this.customInputRangeNumber.Name = "customInputRangeNumber";
|
||||
this.customInputRangeNumber.Size = new System.Drawing.Size(144, 40);
|
||||
this.customInputRangeNumber.TabIndex = 0;
|
||||
this.customInputRangeNumber.Value = new decimal(new int[] { 0, 0, 0, 0});
|
||||
//
|
||||
// buttonCheck
|
||||
//
|
||||
this.buttonCheck.Location = new System.Drawing.Point(193, 29);
|
||||
this.buttonCheck.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.buttonCheck.Name = "buttonCheck";
|
||||
this.buttonCheck.Size = new System.Drawing.Size(144, 31);
|
||||
this.buttonCheck.TabIndex = 1;
|
||||
this.buttonCheck.Text = "Check";
|
||||
this.buttonCheck.UseVisualStyleBackColor = true;
|
||||
this.buttonCheck.Click += new System.EventHandler(this.buttonCheck_Click);
|
||||
//
|
||||
// labelCheckValue
|
||||
//
|
||||
this.labelCheckValue.AutoSize = true;
|
||||
this.labelCheckValue.Location = new System.Drawing.Point(34, 148);
|
||||
this.labelCheckValue.Name = "labelCheckValue";
|
||||
this.labelCheckValue.Size = new System.Drawing.Size(82, 20);
|
||||
this.labelCheckValue.TabIndex = 2;
|
||||
this.labelCheckValue.Text = "Enter value";
|
||||
//
|
||||
// groupBoxInput
|
||||
//
|
||||
this.groupBoxInput.Controls.Add(this.customInputRangeNumber);
|
||||
this.groupBoxInput.Controls.Add(this.labelCheckValue);
|
||||
this.groupBoxInput.Controls.Add(this.buttonCheck);
|
||||
this.groupBoxInput.Location = new System.Drawing.Point(7, 8);
|
||||
this.groupBoxInput.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.groupBoxInput.Name = "groupBoxInput";
|
||||
this.groupBoxInput.Padding = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.groupBoxInput.Size = new System.Drawing.Size(355, 253);
|
||||
this.groupBoxInput.TabIndex = 9;
|
||||
this.groupBoxInput.TabStop = false;
|
||||
this.groupBoxInput.Text = "Input";
|
||||
//
|
||||
// groupBoxSelected
|
||||
//
|
||||
this.groupBoxSelected.Controls.Add(this.buttonGetSelected);
|
||||
this.groupBoxSelected.Controls.Add(this.labelSelectedValue);
|
||||
this.groupBoxSelected.Controls.Add(this.buttonClear);
|
||||
this.groupBoxSelected.Controls.Add(this.buttonAdd);
|
||||
this.groupBoxSelected.Controls.Add(this.textBoxAdd);
|
||||
this.groupBoxSelected.Controls.Add(this.customSelectedCheckedListBoxProperty);
|
||||
this.groupBoxSelected.Location = new System.Drawing.Point(370, 8);
|
||||
this.groupBoxSelected.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.groupBoxSelected.Name = "groupBoxSelected";
|
||||
this.groupBoxSelected.Padding = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.groupBoxSelected.Size = new System.Drawing.Size(355, 253);
|
||||
this.groupBoxSelected.TabIndex = 10;
|
||||
this.groupBoxSelected.TabStop = false;
|
||||
this.groupBoxSelected.Text = "Selected";
|
||||
//
|
||||
// buttonGetSelected
|
||||
//
|
||||
this.buttonGetSelected.Location = new System.Drawing.Point(219, 192);
|
||||
this.buttonGetSelected.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.buttonGetSelected.Name = "buttonGetSelected";
|
||||
this.buttonGetSelected.Size = new System.Drawing.Size(114, 31);
|
||||
this.buttonGetSelected.TabIndex = 14;
|
||||
this.buttonGetSelected.Text = "Get Selected";
|
||||
this.buttonGetSelected.UseVisualStyleBackColor = true;
|
||||
this.buttonGetSelected.Click += new System.EventHandler(this.buttonGetSelected_Click);
|
||||
//
|
||||
// labelSelectedValue
|
||||
//
|
||||
this.labelSelectedValue.AutoSize = true;
|
||||
this.labelSelectedValue.Location = new System.Drawing.Point(219, 148);
|
||||
this.labelSelectedValue.Name = "labelSelectedValue";
|
||||
this.labelSelectedValue.Size = new System.Drawing.Size(105, 20);
|
||||
this.labelSelectedValue.TabIndex = 11;
|
||||
this.labelSelectedValue.Text = "Selected value";
|
||||
//
|
||||
// buttonClear
|
||||
//
|
||||
this.buttonClear.Location = new System.Drawing.Point(219, 108);
|
||||
this.buttonClear.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.buttonClear.Name = "buttonClear";
|
||||
this.buttonClear.Size = new System.Drawing.Size(114, 31);
|
||||
this.buttonClear.TabIndex = 13;
|
||||
this.buttonClear.Text = "Clear";
|
||||
this.buttonClear.UseVisualStyleBackColor = true;
|
||||
this.buttonClear.Click += new System.EventHandler(this.buttonClear_Click);
|
||||
//
|
||||
// buttonAdd
|
||||
//
|
||||
this.buttonAdd.Location = new System.Drawing.Point(219, 69);
|
||||
this.buttonAdd.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.buttonAdd.Name = "buttonAdd";
|
||||
this.buttonAdd.Size = new System.Drawing.Size(114, 31);
|
||||
this.buttonAdd.TabIndex = 12;
|
||||
this.buttonAdd.Text = "Add or Select";
|
||||
this.buttonAdd.UseVisualStyleBackColor = true;
|
||||
this.buttonAdd.Click += new System.EventHandler(this.buttonAdd_Click);
|
||||
//
|
||||
// textBoxAdd
|
||||
//
|
||||
this.textBoxAdd.Location = new System.Drawing.Point(219, 31);
|
||||
this.textBoxAdd.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.textBoxAdd.Name = "textBoxAdd";
|
||||
this.textBoxAdd.Size = new System.Drawing.Size(114, 27);
|
||||
this.textBoxAdd.TabIndex = 11;
|
||||
//
|
||||
// customSelectedCheckedListBoxProperty
|
||||
//
|
||||
this.customSelectedCheckedListBoxProperty.Location = new System.Drawing.Point(41, 25);
|
||||
this.customSelectedCheckedListBoxProperty.Margin = new System.Windows.Forms.Padding(3, 5, 3, 5);
|
||||
this.customSelectedCheckedListBoxProperty.Name = "customSelectedCheckedListBoxProperty";
|
||||
this.customSelectedCheckedListBoxProperty.SelectedElement = "";
|
||||
this.customSelectedCheckedListBoxProperty.Size = new System.Drawing.Size(171, 209);
|
||||
this.customSelectedCheckedListBoxProperty.TabIndex = 0;
|
||||
//
|
||||
// groupBoxData
|
||||
//
|
||||
this.groupBoxData.Controls.Add(this.labelDeviceType);
|
||||
this.groupBoxData.Controls.Add(this.labelModel);
|
||||
this.groupBoxData.Controls.Add(this.labelRegNum);
|
||||
this.groupBoxData.Controls.Add(this.buttonGetFromTree);
|
||||
this.groupBoxData.Controls.Add(this.buttonAddToTree);
|
||||
this.groupBoxData.Controls.Add(this.comboBoxDeviceType);
|
||||
this.groupBoxData.Controls.Add(this.textBoxModel);
|
||||
this.groupBoxData.Controls.Add(this.textBoxSerialNumber);
|
||||
this.groupBoxData.Controls.Add(this.customTreeView);
|
||||
this.groupBoxData.Location = new System.Drawing.Point(7, 269);
|
||||
this.groupBoxData.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.groupBoxData.Name = "groupBoxData";
|
||||
this.groupBoxData.Padding = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.groupBoxData.Size = new System.Drawing.Size(719, 307);
|
||||
this.groupBoxData.TabIndex = 11;
|
||||
this.groupBoxData.TabStop = false;
|
||||
this.groupBoxData.Text = "Data";
|
||||
//
|
||||
// labelDeviceType
|
||||
//
|
||||
this.labelDeviceType.AutoSize = true;
|
||||
this.labelDeviceType.Location = new System.Drawing.Point(494, 155);
|
||||
this.labelDeviceType.Name = "labelDeviceType";
|
||||
this.labelDeviceType.Size = new System.Drawing.Size(119, 20);
|
||||
this.labelDeviceType.TabIndex = 8;
|
||||
this.labelDeviceType.Text = "Тип устройства";
|
||||
//
|
||||
// labelModel
|
||||
//
|
||||
this.labelModel.AutoSize = true;
|
||||
this.labelModel.Location = new System.Drawing.Point(494, 96);
|
||||
this.labelModel.Name = "labelModel";
|
||||
this.labelModel.Size = new System.Drawing.Size(63, 20);
|
||||
this.labelModel.TabIndex = 7;
|
||||
this.labelModel.Text = "Модель";
|
||||
//
|
||||
// labelRegNum
|
||||
//
|
||||
this.labelRegNum.AutoSize = true;
|
||||
this.labelRegNum.Location = new System.Drawing.Point(494, 37);
|
||||
this.labelRegNum.Name = "labelRegNum";
|
||||
this.labelRegNum.Size = new System.Drawing.Size(185, 20);
|
||||
this.labelRegNum.TabIndex = 6;
|
||||
this.labelRegNum.Text = "Регистрационный номер";
|
||||
//
|
||||
// buttonGetFromTree
|
||||
//
|
||||
this.buttonGetFromTree.Location = new System.Drawing.Point(494, 260);
|
||||
this.buttonGetFromTree.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.buttonGetFromTree.Name = "buttonGetFromTree";
|
||||
this.buttonGetFromTree.Size = new System.Drawing.Size(215, 31);
|
||||
this.buttonGetFromTree.TabIndex = 5;
|
||||
this.buttonGetFromTree.Text = "Get Selected";
|
||||
this.buttonGetFromTree.UseVisualStyleBackColor = true;
|
||||
this.buttonGetFromTree.Click += new System.EventHandler(this.buttonGetFromTree_Click);
|
||||
//
|
||||
// buttonAddToTree
|
||||
//
|
||||
this.buttonAddToTree.Location = new System.Drawing.Point(494, 221);
|
||||
this.buttonAddToTree.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.buttonAddToTree.Name = "buttonAddToTree";
|
||||
this.buttonAddToTree.Size = new System.Drawing.Size(215, 31);
|
||||
this.buttonAddToTree.TabIndex = 4;
|
||||
this.buttonAddToTree.Text = "Add";
|
||||
this.buttonAddToTree.UseVisualStyleBackColor = true;
|
||||
this.buttonAddToTree.Click += new System.EventHandler(this.buttonAddToTree_Click);
|
||||
//
|
||||
// comboBoxDeviceType
|
||||
//
|
||||
this.comboBoxDeviceType.FormattingEnabled = true;
|
||||
this.comboBoxDeviceType.Location = new System.Drawing.Point(494, 179);
|
||||
this.comboBoxDeviceType.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.comboBoxDeviceType.Name = "comboBoxDeviceType";
|
||||
this.comboBoxDeviceType.Size = new System.Drawing.Size(214, 28);
|
||||
this.comboBoxDeviceType.TabIndex = 3;
|
||||
//
|
||||
// textBoxModel
|
||||
//
|
||||
this.textBoxModel.Location = new System.Drawing.Point(494, 120);
|
||||
this.textBoxModel.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.textBoxModel.Name = "textBoxModel";
|
||||
this.textBoxModel.Size = new System.Drawing.Size(214, 27);
|
||||
this.textBoxModel.TabIndex = 2;
|
||||
//
|
||||
// textBoxSerialNumber
|
||||
//
|
||||
this.textBoxSerialNumber.Location = new System.Drawing.Point(494, 61);
|
||||
this.textBoxSerialNumber.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.textBoxSerialNumber.Name = "textBoxSerialNumber";
|
||||
this.textBoxSerialNumber.Size = new System.Drawing.Size(214, 27);
|
||||
this.textBoxSerialNumber.TabIndex = 1;
|
||||
//
|
||||
// customTreeView
|
||||
//
|
||||
this.customTreeView.Location = new System.Drawing.Point(17, 29);
|
||||
this.customTreeView.Margin = new System.Windows.Forms.Padding(3, 5, 3, 5);
|
||||
this.customTreeView.Name = "customTreeView";
|
||||
this.customTreeView.Size = new System.Drawing.Size(455, 269);
|
||||
this.customTreeView.TabIndex = 0;
|
||||
//
|
||||
// tabControl
|
||||
//
|
||||
this.tabControl.Controls.Add(this.Visual);
|
||||
this.tabControl.Controls.Add(this.Docs);
|
||||
this.tabControl.Location = new System.Drawing.Point(14, 16);
|
||||
this.tabControl.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.tabControl.Name = "tabControl";
|
||||
this.tabControl.SelectedIndex = 0;
|
||||
this.tabControl.Size = new System.Drawing.Size(746, 621);
|
||||
this.tabControl.TabIndex = 12;
|
||||
//
|
||||
// Visual
|
||||
//
|
||||
this.Visual.Controls.Add(this.groupBoxData);
|
||||
this.Visual.Controls.Add(this.groupBoxInput);
|
||||
this.Visual.Controls.Add(this.groupBoxSelected);
|
||||
this.Visual.Location = new System.Drawing.Point(4, 29);
|
||||
this.Visual.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.Visual.Name = "Visual";
|
||||
this.Visual.Padding = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.Visual.Size = new System.Drawing.Size(738, 588);
|
||||
this.Visual.TabIndex = 0;
|
||||
this.Visual.Text = "Visual";
|
||||
this.Visual.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// Docs
|
||||
//
|
||||
this.Docs.Controls.Add(this.buttonWordWithDiagram);
|
||||
this.Docs.Controls.Add(this.buttonWordWithTable);
|
||||
this.Docs.Controls.Add(this.buttonWordWithImage);
|
||||
this.Docs.Location = new System.Drawing.Point(4, 29);
|
||||
this.Docs.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.Docs.Name = "Docs";
|
||||
this.Docs.Padding = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.Docs.Size = new System.Drawing.Size(738, 588);
|
||||
this.Docs.TabIndex = 1;
|
||||
this.Docs.Text = "Docs";
|
||||
this.Docs.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// buttonWordWithDiagram
|
||||
//
|
||||
this.buttonWordWithDiagram.Location = new System.Drawing.Point(490, 223);
|
||||
this.buttonWordWithDiagram.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.buttonWordWithDiagram.Name = "buttonWordWithDiagram";
|
||||
this.buttonWordWithDiagram.Size = new System.Drawing.Size(227, 97);
|
||||
this.buttonWordWithDiagram.TabIndex = 13;
|
||||
this.buttonWordWithDiagram.Text = "Word With Diagram";
|
||||
this.buttonWordWithDiagram.UseVisualStyleBackColor = true;
|
||||
this.buttonWordWithDiagram.Click += new System.EventHandler(this.buttonWordWithDiagram_Click);
|
||||
//
|
||||
// buttonWordWithTable
|
||||
//
|
||||
this.buttonWordWithTable.Location = new System.Drawing.Point(256, 223);
|
||||
this.buttonWordWithTable.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.buttonWordWithTable.Name = "buttonWordWithTable";
|
||||
this.buttonWordWithTable.Size = new System.Drawing.Size(227, 97);
|
||||
this.buttonWordWithTable.TabIndex = 14;
|
||||
this.buttonWordWithTable.Text = "Word With Table";
|
||||
this.buttonWordWithTable.UseVisualStyleBackColor = true;
|
||||
this.buttonWordWithTable.Click += new System.EventHandler(this.buttonWordWithTable_Click);
|
||||
//
|
||||
// buttonWordWithImage
|
||||
//
|
||||
this.buttonWordWithImage.Location = new System.Drawing.Point(22, 223);
|
||||
this.buttonWordWithImage.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.buttonWordWithImage.Name = "buttonWordWithImage";
|
||||
this.buttonWordWithImage.Size = new System.Drawing.Size(227, 97);
|
||||
this.buttonWordWithImage.TabIndex = 13;
|
||||
this.buttonWordWithImage.Text = "Word With Image";
|
||||
this.buttonWordWithImage.UseVisualStyleBackColor = true;
|
||||
this.buttonWordWithImage.Click += new System.EventHandler(this.buttonWordWithImage_Click);
|
||||
//
|
||||
// FormMain
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(771, 648);
|
||||
this.Controls.Add(this.tabControl);
|
||||
this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.Name = "FormMain";
|
||||
this.Text = "FormMain";
|
||||
this.groupBoxInput.ResumeLayout(false);
|
||||
this.groupBoxInput.PerformLayout();
|
||||
this.groupBoxSelected.ResumeLayout(false);
|
||||
this.groupBoxSelected.PerformLayout();
|
||||
this.groupBoxData.ResumeLayout(false);
|
||||
this.groupBoxData.PerformLayout();
|
||||
this.tabControl.ResumeLayout(false);
|
||||
this.Visual.ResumeLayout(false);
|
||||
this.Docs.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private MyCustomComponents.CustomInputRangeNumber customInputRangeNumber;
|
||||
private TextBox textBoxMin;
|
||||
private TextBox textBoxMax;
|
||||
private Button buttonCheck;
|
||||
private Label labelCheckValue;
|
||||
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 labelRegNum;
|
||||
private TabControl tabControl;
|
||||
private TabPage Visual;
|
||||
private TabPage Docs;
|
||||
private Button buttonWordWithImage;
|
||||
private MyCustomComponents.WordWithImages wordWithImages;
|
||||
private Button buttonWordWithTable;
|
||||
private MyCustomComponents.WordWithTable wordWithTable;
|
||||
private Button buttonWordWithDiagram;
|
||||
private MyCustomComponents.WordWithDiagram wordWithDiagram;
|
||||
}
|
||||
}
|
255
Lab 2/Belianin_2/DesktopWithMyVisualComponents/FormMain.cs
Normal file
255
Lab 2/Belianin_2/DesktopWithMyVisualComponents/FormMain.cs
Normal file
@ -0,0 +1,255 @@
|
||||
using MyCustomComponents;
|
||||
using MyCustomComponents.Models;
|
||||
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", Owner = "Иван Иванов", PurchaseDate = new DateTime(2022, 5, 15), State = "Новый", Price = 70000, Color = "Синий", WarrantyPeriod = 6 },
|
||||
new Device { Id = 2, SerialNumber = "CO2UD8471", DeviceType = "Ноутбук", Model = "MacBook Pro", Owner = "Петр Петров", PurchaseDate = new DateTime(2021, 3, 20), State = "Б/У", Price = 150000, Color = "Черный", WarrantyPeriod = 12 },
|
||||
new Device { Id = 3, SerialNumber = "R80NZD8812", DeviceType = "Умные часы", Model = "Galaxy Watch 4", Owner = "Анна Смирнова", PurchaseDate = new DateTime(2023, 1, 10), State = "Новый", Price = 25000, Color = "Белый", WarrantyPeriod = 18 },
|
||||
new Device { Id = 4, SerialNumber = "SM-G3412", DeviceType = "Мобильный телефон", Model = "Samsung Galaxy S24", Owner = "Елена Кузнецова", PurchaseDate = new DateTime(2023, 7, 25), State = "Новый", Price = 80000, Color = "Синий", WarrantyPeriod = 6 },
|
||||
new Device { Id = 5, SerialNumber = "FN738214", DeviceType = "Умные часы", Model = "Apple Watch 3", Owner = "Дмитрий Федоров", PurchaseDate = new DateTime(2020, 8, 5), State = "Б/У", Price = 15000, Color = "Красный", WarrantyPeriod = 24 },
|
||||
};
|
||||
|
||||
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();
|
||||
|
||||
customTreeView.SelectedTreeNode = 2;
|
||||
|
||||
// Присоединить обработчик события при изменении значения
|
||||
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;
|
||||
}
|
||||
|
||||
private void buttonWordWithImage_Click(object sender, EventArgs e)
|
||||
{
|
||||
var openFileDialog = new OpenFileDialog();
|
||||
bool flag = true;
|
||||
var images = new List<byte[]>();
|
||||
while (flag)
|
||||
{
|
||||
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
images.Add(File.ReadAllBytes(openFileDialog.FileName));
|
||||
}
|
||||
else
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
wordWithImages.CreateDoc(new WordWithImageConfig
|
||||
{
|
||||
FilePath = "E:\\COP\\Lab 2\\WordWithImageDocx.docx",
|
||||
Header = "Картинки:",
|
||||
Images = images,
|
||||
});
|
||||
}
|
||||
|
||||
private void buttonWordWithTable_Click(object sender, EventArgs e)
|
||||
{
|
||||
wordWithTable.CreateDoc(new WordWithTableDataConfig<Device>
|
||||
{
|
||||
FilePath = "E:\\COP\\Lab 2\\WordWithTableDocx.docx",
|
||||
Header = "Таблица:",
|
||||
UseUnion = true,
|
||||
ColumnsRowsWidth = new List<(int, int)> { (0, 5), (0, 5), (0, 10), (0, 10), (0, 7), (0, 7), (0, 10), (0, 10), (0, 8) },
|
||||
ColumnUnion = new List<(int StartIndex, int Count)> { (2, 3), (5, 3) },
|
||||
Headers = new List<(int ColumnIndex, int RowIndex, string Header, string PropertyName)>
|
||||
{
|
||||
(0, 0, "Номер", "Id"),
|
||||
(1, 0, "Серийный номер", "SerialNumber"),
|
||||
(2, 0, "Об устройстве", "DeviceType"),
|
||||
(2, 1, "Модель", "Model"),
|
||||
(3, 1, "Цвет", "Color"),
|
||||
(4, 1, "Стоимость", "Price"),
|
||||
(5, 0, "Покупатели", ""),
|
||||
(5, 1, "Дата покупки", "PurchaseDate"),
|
||||
(6, 1, "Владелец", "Owner"),
|
||||
(7, 1, "Статус", "State"),
|
||||
(8, 0, "Гарантия", "WarrantyPeriod"),
|
||||
},
|
||||
Data = devices
|
||||
});
|
||||
}
|
||||
|
||||
private void buttonWordWithDiagram_Click(object sender, EventArgs e)
|
||||
{
|
||||
wordWithDiagram.CreateDoc(new WordWithDiagramConfig
|
||||
{
|
||||
FilePath = "E:\\COP\\Lab 2\\WordWithDiagramDocx.docx",
|
||||
Header = "Диаграмма",
|
||||
ChartTitle = "Круговая диаграмма",
|
||||
LegendLocation = MyCustomComponents.Models.Location.Bottom,
|
||||
Data = new Dictionary<string, List<(int Date, double Value)>>
|
||||
{
|
||||
{ "Серия 1", new List<(int Date, double Value)> { (1, 20), (2, 30), (3, 50) } }
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
69
Lab 2/Belianin_2/DesktopWithMyVisualComponents/FormMain.resx
Normal file
69
Lab 2/Belianin_2/DesktopWithMyVisualComponents/FormMain.resx
Normal file
@ -0,0 +1,69 @@
|
||||
<root>
|
||||
<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>
|
||||
<metadata name="wordWithImages.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="wordWithTable.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>161, 17</value>
|
||||
</metadata>
|
||||
<metadata name="wordWithDiagram.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>295, 17</value>
|
||||
</metadata>
|
||||
</root>
|
17
Lab 2/Belianin_2/DesktopWithMyVisualComponents/Program.cs
Normal file
17
Lab 2/Belianin_2/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 2/Belianin_2/MyCustomComponents/CustomInputRangeNumber.Designer.cs
generated
Normal file
59
Lab 2/Belianin_2/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 2/Belianin_2/MyCustomComponents/CustomInputRangeNumber.cs
Normal file
122
Lab 2/Belianin_2/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 2/Belianin_2/MyCustomComponents/CustomInputRangeNumber.resx
Normal file
120
Lab 2/Belianin_2/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 2/Belianin_2/MyCustomComponents/CustomSelectedCheckedListBoxProperty.Designer.cs
generated
Normal file
56
Lab 2/Belianin_2/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.SelectedItem.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 2/Belianin_2/MyCustomComponents/CustomTreeView.Designer.cs
generated
Normal file
55
Lab 2/Belianin_2/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;
|
||||
}
|
||||
}
|
168
Lab 2/Belianin_2/MyCustomComponents/CustomTreeView.cs
Normal file
168
Lab 2/Belianin_2/MyCustomComponents/CustomTreeView.cs
Normal file
@ -0,0 +1,168 @@
|
||||
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");
|
||||
}
|
||||
|
||||
// Получаем первый узел в дереве
|
||||
TreeNode currentNode = null;
|
||||
|
||||
// Проходимся по иерархии
|
||||
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 2/Belianin_2/MyCustomComponents/CustomTreeView.resx
Normal file
120
Lab 2/Belianin_2/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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
289
Lab 2/Belianin_2/MyCustomComponents/Helpers/CreatorDiagram.cs
Normal file
289
Lab 2/Belianin_2/MyCustomComponents/Helpers/CreatorDiagram.cs
Normal file
@ -0,0 +1,289 @@
|
||||
using DocumentFormat.OpenXml;
|
||||
using DocumentFormat.OpenXml.Drawing;
|
||||
using DocumentFormat.OpenXml.Drawing.Charts;
|
||||
using MyCustomComponents.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyCustomComponents.Helpers
|
||||
{
|
||||
// Класс CreatorDiagram отвечает за создание диаграмм
|
||||
public class CreatorDiagram
|
||||
{
|
||||
// Порядок и индекс используются для нумерации серий на диаграмме
|
||||
private static uint order = 0u;
|
||||
|
||||
private static uint index = 1u;
|
||||
|
||||
// Метод GeneratePieChart генерирует круговую диаграмму на основе конфигурации
|
||||
public static DocumentFormat.OpenXml.Drawing.Charts.Chart GeneratePieChart(WordWithDiagramConfig config)
|
||||
{
|
||||
// Создаем объект PieChart
|
||||
PieChart pieChart = new PieChart();
|
||||
|
||||
// Добавляем первую серию данных в диаграмму
|
||||
pieChart.Append(GeneratePieChartSeries(config.Data.First().Key, config.Data.First().Value));
|
||||
|
||||
// Создаем область построения (PlotArea) для диаграммы
|
||||
// Добавляем макет для более гибкого управления размещением элементов. Добавляем круговую диаграмму в область построения
|
||||
PlotArea plotArea = new PlotArea();
|
||||
plotArea.Append(new Layout());
|
||||
plotArea.Append(pieChart);
|
||||
|
||||
// Возвращаем объект диаграммы с заголовком и расположением легенды
|
||||
return GenerateChart(config.ChartTitle, plotArea, config.LegendLocation);
|
||||
}
|
||||
|
||||
private static DocumentFormat.OpenXml.Drawing.Charts.Chart GenerateChart(string titleText, PlotArea plotArea, Location legendLocation)
|
||||
{
|
||||
DocumentFormat.OpenXml.Drawing.Charts.Chart chart = new DocumentFormat.OpenXml.Drawing.Charts.Chart();
|
||||
|
||||
// Проверяем текст заголовка и добавляем его
|
||||
if (titleText.HaveText())
|
||||
{
|
||||
chart.Append(GenerateTitle(titleText));
|
||||
}
|
||||
else
|
||||
{
|
||||
chart.Append(new AutoTitleDeleted
|
||||
{
|
||||
Val = (BooleanValue)true
|
||||
});
|
||||
}
|
||||
|
||||
// Определяем позицию легенды на основе переданного значения
|
||||
LegendPositionValues position = legendLocation switch
|
||||
{
|
||||
Location.Top => LegendPositionValues.Top,
|
||||
Location.Right => LegendPositionValues.Right,
|
||||
Location.Left => LegendPositionValues.Left,
|
||||
_ => LegendPositionValues.Bottom,
|
||||
};
|
||||
|
||||
// Добавляем область построения и легенду к диаграмме
|
||||
chart.Append(plotArea);
|
||||
chart.Append(GenerateLegend(position));
|
||||
|
||||
// Устанавливаем видимость только для отображаемых данных
|
||||
chart.Append(new PlotVisibleOnly
|
||||
{
|
||||
Val = (BooleanValue)true
|
||||
});
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
// Метод создает объект легенды для диаграммы
|
||||
private static Legend GenerateLegend(LegendPositionValues position)
|
||||
{
|
||||
// Свойства текста для легенды
|
||||
ParagraphProperties paragraphProperties = new ParagraphProperties();
|
||||
paragraphProperties.Append(new DefaultRunProperties());
|
||||
|
||||
Paragraph paragraph = new Paragraph();
|
||||
paragraph.Append(paragraphProperties);
|
||||
paragraph.Append(new EndParagraphRunProperties());
|
||||
|
||||
TextProperties textProperties = new TextProperties();
|
||||
textProperties.Append(new BodyProperties());
|
||||
textProperties.Append(new ListStyle());
|
||||
textProperties.Append(paragraph);
|
||||
|
||||
// Создаем объект легенды с заданной позицией
|
||||
Legend legend = new Legend();
|
||||
legend.Append(new LegendPosition
|
||||
{
|
||||
Val = (EnumValue<LegendPositionValues>)position
|
||||
});
|
||||
|
||||
legend.Append(new Layout());
|
||||
legend.Append(new Overlay
|
||||
{
|
||||
Val = (BooleanValue)false
|
||||
});
|
||||
|
||||
// Добавляем свойства текста к легенде
|
||||
legend.Append(textProperties);
|
||||
|
||||
return legend;
|
||||
}
|
||||
|
||||
// Метод создает объект заголовка для диаграммы
|
||||
private static Title GenerateTitle(string titleText)
|
||||
{
|
||||
// Создаем объект Run для текста заголовка
|
||||
Run run = new Run();
|
||||
run.Append(new RunProperties
|
||||
{
|
||||
FontSize = (Int32Value)1100
|
||||
});
|
||||
|
||||
run.Append(new Text(titleText)); // Добавялем текст заголовка
|
||||
|
||||
// Свойства абзаца для заголовка
|
||||
ParagraphProperties paragraphProperties = new ParagraphProperties();
|
||||
paragraphProperties.Append(new DefaultRunProperties
|
||||
{
|
||||
FontSize = (Int32Value)1100
|
||||
});
|
||||
|
||||
Paragraph paragraph = new Paragraph();
|
||||
paragraph.Append(paragraphProperties);
|
||||
paragraph.Append(run);
|
||||
|
||||
// Создаем RichText, чтобы включить заголовок в диаграмму
|
||||
RichText richText = new RichText();
|
||||
richText.Append(new BodyProperties());
|
||||
richText.Append(new ListStyle());
|
||||
richText.Append(paragraph);
|
||||
|
||||
ChartText chartText = new ChartText();
|
||||
chartText.Append(richText);
|
||||
|
||||
// Создаем объект Title, содержащий текст заголовка
|
||||
Title title = new Title();
|
||||
title.Append(chartText);
|
||||
title.Append(new Layout()); // Добавляем макет
|
||||
|
||||
// Производим наложение
|
||||
title.Append(new Overlay
|
||||
{
|
||||
Val = (BooleanValue)false
|
||||
});
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
// Метод создает текст для серий данных
|
||||
private static SeriesText GenerateSeriesText(string seriesName)
|
||||
{
|
||||
StringPoint stringPoint = new StringPoint
|
||||
{
|
||||
Index = (UInt32Value)0u
|
||||
};
|
||||
|
||||
stringPoint.Append(new NumericValue
|
||||
{
|
||||
Text = seriesName
|
||||
});
|
||||
|
||||
// Кэш строковых значений
|
||||
StringCache stringCache = new StringCache();
|
||||
stringCache.Append(new PointCount
|
||||
{
|
||||
Val = (UInt32Value)1u
|
||||
});
|
||||
|
||||
stringCache.Append(stringPoint);
|
||||
|
||||
StringReference stringReference = new StringReference();
|
||||
stringReference.Append(stringCache);
|
||||
|
||||
SeriesText seriesText = new SeriesText();
|
||||
seriesText.Append(stringReference);
|
||||
|
||||
return seriesText;
|
||||
}
|
||||
|
||||
// Метод создает данные оси категорий
|
||||
private static CategoryAxisData GenerateCategoryAxisData(string[] data)
|
||||
{
|
||||
uint number = (uint)data.Length;
|
||||
NumberingCache numberingCache = GenerateNumberingCache(number);
|
||||
|
||||
for (uint number2 = 0u; number2 < number; number2++)
|
||||
{
|
||||
numberingCache.Append(GenerateNumericPoint(number2, data[number2].ToString()));
|
||||
}
|
||||
|
||||
NumberReference numberReference = new NumberReference();
|
||||
numberReference.Append(numberingCache);
|
||||
|
||||
CategoryAxisData categoryAxisData = new CategoryAxisData();
|
||||
categoryAxisData.Append(numberReference);
|
||||
|
||||
return categoryAxisData;
|
||||
}
|
||||
|
||||
// Метод создает объект значений для диаграммы
|
||||
private static Values GenerateValues(double[] data)
|
||||
{
|
||||
uint number = (uint)data.Length;
|
||||
NumberingCache numberingCache = GenerateNumberingCache(number);
|
||||
|
||||
for (uint number2 = 0u; number2 < number; number2++)
|
||||
{
|
||||
numberingCache.Append(GenerateNumericPoint(number2, data[number2].ToString()));
|
||||
}
|
||||
|
||||
NumberReference numberReference = new NumberReference();
|
||||
numberReference.Append(numberingCache);
|
||||
|
||||
Values values = new Values();
|
||||
values.Append(numberReference);
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
// Метод создает кэш для числовых данных
|
||||
private static NumberingCache GenerateNumberingCache(uint numberPoints)
|
||||
{
|
||||
NumberingCache numberingCache = new NumberingCache();
|
||||
numberingCache.Append(new FormatCode
|
||||
{
|
||||
Text = "General"
|
||||
});
|
||||
|
||||
numberingCache.Append(new PointCount
|
||||
{
|
||||
Val = (UInt32Value)numberPoints
|
||||
});
|
||||
|
||||
return numberingCache;
|
||||
}
|
||||
|
||||
// Метод создает числовую точку данных
|
||||
private static NumericPoint GenerateNumericPoint(UInt32Value idx, string text)
|
||||
{
|
||||
NumericPoint numericPoint = new NumericPoint
|
||||
{
|
||||
Index = idx
|
||||
};
|
||||
numericPoint.Append(new NumericValue
|
||||
{
|
||||
Text = text
|
||||
});
|
||||
|
||||
return numericPoint;
|
||||
}
|
||||
|
||||
// Метод создает серию данных для круговой диаграммы
|
||||
private static PieChartSeries GeneratePieChartSeries(string seriesName, List<(int Date, double Value)> data)
|
||||
{
|
||||
// Создаем объект серии для круговой диаграммы
|
||||
PieChartSeries pieChartSeries = new PieChartSeries();
|
||||
pieChartSeries.Append(new DocumentFormat.OpenXml.Drawing.Charts.Index
|
||||
{
|
||||
Val = (UInt32Value)index
|
||||
});
|
||||
pieChartSeries.Append(new Order
|
||||
{
|
||||
Val = (UInt32Value)order
|
||||
});
|
||||
|
||||
// Добавляем текст серии, данные оси категорий и значения
|
||||
pieChartSeries.Append(GenerateSeriesText(seriesName));
|
||||
pieChartSeries.Append(GenerateCategoryAxisData(data.Select(((int Date, double Value) c) => c.Date.ToString()).ToArray()));
|
||||
pieChartSeries.Append(GenerateValues(data.Select(((int Date, double Value) v) => v.Value).ToArray()));
|
||||
|
||||
index++;
|
||||
order++;
|
||||
|
||||
return pieChartSeries;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
157
Lab 2/Belianin_2/MyCustomComponents/Helpers/DiagramService.cs
Normal file
157
Lab 2/Belianin_2/MyCustomComponents/Helpers/DiagramService.cs
Normal file
@ -0,0 +1,157 @@
|
||||
using DocumentFormat.OpenXml.Drawing.Charts;
|
||||
using DocumentFormat.OpenXml.Drawing;
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml;
|
||||
using MyCustomComponents.Models;
|
||||
using System;
|
||||
using DocumentFormat.OpenXml.Drawing.Wordprocessing;
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
|
||||
namespace MyCustomComponents.Helpers
|
||||
{
|
||||
public class DiagramService
|
||||
{
|
||||
// Хранит документ Word
|
||||
private Document _document = null;
|
||||
|
||||
// Хранит тело документа Word
|
||||
private Body _body = null;
|
||||
|
||||
// Хранит диаграмму (график), которая будет добавлена в документ
|
||||
private DocumentFormat.OpenXml.Drawing.Charts.Chart _chart;
|
||||
|
||||
// Свойство для создания или получения документа
|
||||
private Document Document
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_document == null)
|
||||
{
|
||||
_document = new Document();
|
||||
}
|
||||
|
||||
return _document;
|
||||
}
|
||||
}
|
||||
|
||||
// Свойство для создания или получения тела документа
|
||||
private Body Body
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_body == null)
|
||||
{
|
||||
_body = Document.AppendChild(new Body());
|
||||
}
|
||||
|
||||
return _body;
|
||||
}
|
||||
}
|
||||
|
||||
public DiagramService()
|
||||
{
|
||||
_document = new Document();
|
||||
_body = _document.AppendChild(new Body());
|
||||
}
|
||||
|
||||
// Метод для создания документа с диаграммой
|
||||
public void CreateHeader(string header)
|
||||
{
|
||||
DocumentFormat.OpenXml.Wordprocessing.Paragraph paragraph = Body.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Paragraph());
|
||||
DocumentFormat.OpenXml.Wordprocessing.Run run = paragraph.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Run());
|
||||
|
||||
run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.RunProperties(new Bold()));
|
||||
run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text(header));
|
||||
}
|
||||
|
||||
public void SaveDoc(string filepath)
|
||||
{
|
||||
if (filepath.IsEmpty())
|
||||
{
|
||||
throw new ArgumentNullException("Имя файла не задано");
|
||||
}
|
||||
|
||||
if (_document == null || _body == null)
|
||||
{
|
||||
throw new ArgumentNullException("Документ не сформирован, сохранять нечего");
|
||||
}
|
||||
|
||||
using WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Create(filepath, WordprocessingDocumentType.Document);
|
||||
MainDocumentPart mainDocumentPart = wordprocessingDocument.AddMainDocumentPart();
|
||||
mainDocumentPart.Document = Document;
|
||||
|
||||
if (_chart != null)
|
||||
{
|
||||
ChartPart chartPart = mainDocumentPart.AddNewPart<ChartPart>("rId110");
|
||||
ChartSpace chartSpace = new ChartSpace();
|
||||
chartSpace.Append(new EditingLanguage
|
||||
{
|
||||
Val = (StringValue)"en-us"
|
||||
});
|
||||
|
||||
chartSpace.Append(_chart);
|
||||
ChartShapeProperties chartShapeProperties = new ChartShapeProperties();
|
||||
DocumentFormat.OpenXml.Drawing.Outline outline = new DocumentFormat.OpenXml.Drawing.Outline();
|
||||
|
||||
outline.Append(new NoFill());
|
||||
chartShapeProperties.Append(outline);
|
||||
chartSpace.Append(chartShapeProperties);
|
||||
chartPart.ChartSpace = chartSpace;
|
||||
|
||||
GeneratePartContent(mainDocumentPart);
|
||||
}
|
||||
}
|
||||
|
||||
private static void GeneratePartContent(MainDocumentPart mainPart)
|
||||
{
|
||||
DocumentFormat.OpenXml.Wordprocessing.Paragraph paragraph = new DocumentFormat.OpenXml.Wordprocessing.Paragraph
|
||||
{
|
||||
RsidParagraphAddition = (HexBinaryValue)"00C75AEB",
|
||||
RsidRunAdditionDefault = (HexBinaryValue)"000F3EFF"
|
||||
};
|
||||
|
||||
DocumentFormat.OpenXml.Wordprocessing.Run run = new DocumentFormat.OpenXml.Wordprocessing.Run();
|
||||
Drawing drawing = new Drawing();
|
||||
Inline inline = new Inline();
|
||||
|
||||
inline.Append(new Extent
|
||||
{
|
||||
Cx = (Int64Value)5274310L,
|
||||
Cy = (Int64Value)3076575L
|
||||
});
|
||||
|
||||
DocProperties docProperties = new DocProperties
|
||||
{
|
||||
Id = (UInt32Value)1u,
|
||||
Name = (StringValue)"Chart 1"
|
||||
};
|
||||
|
||||
inline.Append(docProperties);
|
||||
Graphic graphic = new Graphic();
|
||||
|
||||
GraphicData graphicData = new GraphicData
|
||||
{
|
||||
Uri = (StringValue)"http://schemas.openxmlformats.org/drawingml/2006/chart"
|
||||
};
|
||||
|
||||
ChartReference chartReference = new ChartReference
|
||||
{
|
||||
Id = (StringValue)"rId110"
|
||||
};
|
||||
|
||||
graphicData.Append(chartReference);
|
||||
graphic.Append(graphicData);
|
||||
inline.Append(graphic);
|
||||
drawing.Append(inline);
|
||||
|
||||
run.Append(drawing);
|
||||
paragraph.Append(run);
|
||||
mainPart.Document.Body!.Append(paragraph);
|
||||
}
|
||||
|
||||
public void CreatePieChart(WordWithDiagramConfig config)
|
||||
{
|
||||
_chart = CreatorDiagram.GeneratePieChart(config);
|
||||
}
|
||||
}
|
||||
}
|
210
Lab 2/Belianin_2/MyCustomComponents/Helpers/ExtensionConfig.cs
Normal file
210
Lab 2/Belianin_2/MyCustomComponents/Helpers/ExtensionConfig.cs
Normal file
@ -0,0 +1,210 @@
|
||||
using MyCustomComponents.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyCustomComponents.Helpers
|
||||
{
|
||||
public static class ExtensionConfig
|
||||
{
|
||||
// Проверяет поля в объекте WordConfig
|
||||
public static void CheckFields(this WordConfig config)
|
||||
{
|
||||
if (config.FilePath.IsEmpty())
|
||||
{
|
||||
throw new ArgumentNullException("Имя файла не задано");
|
||||
}
|
||||
|
||||
if (config.Header.IsEmpty())
|
||||
{
|
||||
throw new ArgumentNullException("Заголовок документа не задан");
|
||||
}
|
||||
}
|
||||
|
||||
// Проверяет поля в объекте WordWithDiagramConfig
|
||||
public static void CheckFields(this WordWithDiagramConfig config)
|
||||
{
|
||||
// Используем метод проверки базового WordConfig
|
||||
((WordConfig)config).CheckFields();
|
||||
|
||||
if (config.ChartTitle.IsEmpty())
|
||||
{
|
||||
throw new ArgumentNullException("Заголовок диаграммы не задан");
|
||||
}
|
||||
|
||||
// Проверка на наличие данных для диаграммы
|
||||
if (config.Data == null || config.Data.Count == 0 || config.Data.Any<KeyValuePair<string, List<(int, double)>>>
|
||||
((KeyValuePair<string, List<(int Date, double Value)>> x) => x.Key.IsEmpty() || x.Value == null || x.Value.Count == 0))
|
||||
{
|
||||
throw new ArgumentNullException("Нет данных для заполнения диаграммы");
|
||||
}
|
||||
}
|
||||
|
||||
// Проверяет поля в объекте WordWithImageConfig
|
||||
public static void CheckFields(this WordWithImageConfig config)
|
||||
{
|
||||
// Используем метод проверки базового WordConfig
|
||||
((WordConfig)config).CheckFields();
|
||||
|
||||
// Проверка на наличие изображений
|
||||
if (config.Images == null || config.Images.Count == 0 || config.Images.All((byte[] x) => x == null || x.Length == 0))
|
||||
{
|
||||
throw new ArgumentNullException("Нет изображений для вставки в документ");
|
||||
}
|
||||
}
|
||||
|
||||
// Универсальный метод проверки полей для WordWithTableDataConfig
|
||||
public static void CheckFields<T>(this WordWithTableDataConfig<T> config)
|
||||
{
|
||||
WordWithTableDataConfig<T> config2 = config;
|
||||
|
||||
// Используем метод проверки базового WordConfig
|
||||
((WordConfig)config2).CheckFields();
|
||||
|
||||
// Проверка на наличие данных по ширине колонок
|
||||
if (config2.ColumnsRowsWidth == null || config2.ColumnsRowsWidth.Count == 0)
|
||||
{
|
||||
throw new ArgumentNullException("Нет данных по ширине колонок таблицы");
|
||||
}
|
||||
|
||||
// Проверка на наличие данных по объединению колонок (если используется объединение)
|
||||
if (config2.UseUnion && (config2.ColumnUnion == null || config2.ColumnUnion.Count == 0))
|
||||
{
|
||||
throw new ArgumentNullException("Нет данных по объединению колонок таблицы");
|
||||
}
|
||||
|
||||
// Проверка заголовков таблицы
|
||||
if (config2.Headers == null || config2.Headers.Count == 0 || config2.Headers.Any<(int, int, string, string)>(((int ColumnIndex, int RowIndex, string Header, string PropertyName) x) => x.Header.IsEmpty()))
|
||||
{
|
||||
throw new ArgumentNullException("Нет данных по заголовкам таблицы");
|
||||
}
|
||||
|
||||
// Проверка на наличие данных для таблицы
|
||||
if (config2.Data == null || config2.Data.Count == 0)
|
||||
{
|
||||
throw new ArgumentNullException("Нет данных для заполнения таблицы");
|
||||
}
|
||||
|
||||
// Если объединение колонок не используется, выходим из метода
|
||||
if (!config2.UseUnion)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверка на выход объединения ячеек за границы таблицы
|
||||
if (config2.ColumnsRowsWidth.Count < config2.ColumnUnion[config2.ColumnUnion.Count - 1].StartIndex + config2.ColumnUnion[config2.ColumnUnion.Count - 1].Count - 1)
|
||||
{
|
||||
throw new IndexOutOfRangeException("Последнее объединение ячеек выходит за границы таблицы");
|
||||
}
|
||||
|
||||
// Проверка заголовков для колонок до объединений
|
||||
int k;
|
||||
for (k = 0; k < config2.ColumnUnion[0].StartIndex; k++)
|
||||
{
|
||||
int number = config2.Headers.Where<(int, int, string, string)>(((int ColumnIndex, int RowIndex, string Header, string PropertyName) x) => x.ColumnIndex == k).Count();
|
||||
if (number == 0)
|
||||
{
|
||||
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(34, 1);
|
||||
defaultInterpolatedStringHandler.AppendLiteral("Для ");
|
||||
defaultInterpolatedStringHandler.AppendFormatted(k);
|
||||
defaultInterpolatedStringHandler.AppendLiteral(" колонки отсутствует заголовок");
|
||||
throw new ArgumentNullException(defaultInterpolatedStringHandler.ToStringAndClear());
|
||||
}
|
||||
|
||||
if (number > 1)
|
||||
{
|
||||
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(37, 1);
|
||||
defaultInterpolatedStringHandler.AppendLiteral("Для ");
|
||||
defaultInterpolatedStringHandler.AppendFormatted(k);
|
||||
defaultInterpolatedStringHandler.AppendLiteral(" колонки задано более 1 заголовка");
|
||||
throw new ArgumentNullException(defaultInterpolatedStringHandler.ToStringAndClear());
|
||||
}
|
||||
}
|
||||
|
||||
// Проверка объединений колонок на накладки
|
||||
int j;
|
||||
for (j = 0; j < config2.ColumnUnion.Count; j++)
|
||||
{
|
||||
if (j < config2.ColumnUnion.Count - 1 && config2.ColumnUnion[j].StartIndex + config2.ColumnUnion[j].Count - 1 > config2.ColumnUnion[j + 1].StartIndex)
|
||||
{
|
||||
throw new IndexOutOfRangeException("Имеется накладка в объединении ячеек");
|
||||
}
|
||||
|
||||
// Проверка заголовков для колонок 0 и 1 строк
|
||||
int number2 = config2.Headers.Where<(int, int, string, string)>(((int ColumnIndex, int RowIndex, string Header, string PropertyName) x) => x.ColumnIndex >= config2.ColumnUnion[j].StartIndex && x.ColumnIndex <= config2.ColumnUnion[j].StartIndex + config2.ColumnUnion[j].Count - 1 && x.RowIndex == 0).Count();
|
||||
if (number2 == 0)
|
||||
{
|
||||
throw new ArgumentNullException("Для колонок 0 строки отсутствует заголовок");
|
||||
}
|
||||
|
||||
if (number2 > 1)
|
||||
{
|
||||
throw new ArgumentNullException("Для колонок 0 строки задано более 1 заголовка");
|
||||
}
|
||||
|
||||
number2 = config2.Headers.Where<(int, int, string, string)>(((int ColumnIndex, int RowIndex, string Header, string PropertyName) x) => x.ColumnIndex >= config2.ColumnUnion[j].StartIndex && x.ColumnIndex <= config2.ColumnUnion[j].StartIndex + config2.ColumnUnion[j].Count - 1 && x.RowIndex == 1).Count();
|
||||
if (number2 < config2.ColumnUnion[j].Count)
|
||||
{
|
||||
throw new ArgumentNullException("Для колонок 1 строки не хватает заголовков");
|
||||
}
|
||||
|
||||
if (number2 > config2.ColumnUnion[j].Count)
|
||||
{
|
||||
throw new ArgumentNullException("Для колонок 1 строки задано более требуемого числа заголовков");
|
||||
}
|
||||
|
||||
// Проверка заголовков для колонок между объединениями
|
||||
if (j < config2.ColumnUnion.Count - 1)
|
||||
{
|
||||
number2 = config2.Headers.Where<(int, int, string, string)>(((int ColumnIndex, int RowIndex, string Header, string PropertyName) x) => x.ColumnIndex >= config2.ColumnUnion[j].StartIndex + config2.ColumnUnion[j].Count && x.ColumnIndex < config2.ColumnUnion[j + 1].StartIndex && x.RowIndex == 0).Count();
|
||||
|
||||
if (number2 < config2.ColumnUnion[j + 1].StartIndex - (config2.ColumnUnion[j].StartIndex + config2.ColumnUnion[j].Count))
|
||||
{
|
||||
throw new ArgumentNullException("Для колонок не хватает заголовков");
|
||||
}
|
||||
|
||||
if (number2 > config2.ColumnUnion[j + 1].StartIndex - (config2.ColumnUnion[j].StartIndex + config2.ColumnUnion[j].Count))
|
||||
{
|
||||
throw new ArgumentNullException("Для колонок задано более требуемого числа заголовков");
|
||||
}
|
||||
|
||||
number2 = config2.Headers.Where<(int, int, string, string)>(((int ColumnIndex, int RowIndex, string Header, string PropertyName) x) => x.ColumnIndex >= config2.ColumnUnion[j].StartIndex + config2.ColumnUnion[j].Count && x.ColumnIndex < config2.ColumnUnion[j + 1].StartIndex && x.RowIndex == 1).Count();
|
||||
|
||||
if (number2 > 0)
|
||||
{
|
||||
throw new ArgumentNullException("Для колонок заданы заголовки 2 уровня, чего быть не должно");
|
||||
}
|
||||
}
|
||||
|
||||
// Проверка заголовков для оставшихся колонок после последнего объединения
|
||||
int i;
|
||||
|
||||
for (i = config2.ColumnUnion[config2.ColumnUnion.Count - 1].StartIndex + config2.ColumnUnion[config2.ColumnUnion.Count - 1].Count; i < config2.ColumnsRowsWidth.Count; i++)
|
||||
{
|
||||
int number3 = config2.Headers.Where<(int, int, string, string)>(((int ColumnIndex, int RowIndex, string Header, string PropertyName) x) => x.ColumnIndex == i).Count();
|
||||
|
||||
if (number3 == 0)
|
||||
{
|
||||
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(34, 1);
|
||||
defaultInterpolatedStringHandler.AppendLiteral("Для ");
|
||||
defaultInterpolatedStringHandler.AppendFormatted(i);
|
||||
defaultInterpolatedStringHandler.AppendLiteral(" колонки отсутствует заголовок");
|
||||
throw new ArgumentNullException(defaultInterpolatedStringHandler.ToStringAndClear());
|
||||
}
|
||||
|
||||
if (number3 > 1)
|
||||
{
|
||||
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(37, 1);
|
||||
defaultInterpolatedStringHandler.AppendLiteral("Для ");
|
||||
defaultInterpolatedStringHandler.AppendFormatted(i);
|
||||
defaultInterpolatedStringHandler.AppendLiteral(" колонки задано более 1 заголовка");
|
||||
throw new ArgumentNullException(defaultInterpolatedStringHandler.ToStringAndClear());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyCustomComponents.Helpers
|
||||
{
|
||||
public static class ExtensionString
|
||||
{
|
||||
public static bool HaveText(this string str)
|
||||
{
|
||||
return !string.IsNullOrEmpty(str);
|
||||
}
|
||||
|
||||
public static bool IsEmpty(this string str)
|
||||
{
|
||||
return string.IsNullOrEmpty(str);
|
||||
}
|
||||
}
|
||||
}
|
209
Lab 2/Belianin_2/MyCustomComponents/Helpers/ImageService.cs
Normal file
209
Lab 2/Belianin_2/MyCustomComponents/Helpers/ImageService.cs
Normal file
@ -0,0 +1,209 @@
|
||||
using DocumentFormat.OpenXml.Drawing.Wordprocessing;
|
||||
using DocumentFormat.OpenXml.Drawing;
|
||||
using DocumentFormat.OpenXml;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
|
||||
namespace MyCustomComponents.Helpers
|
||||
{
|
||||
public class ImageService
|
||||
{
|
||||
// Хранит документ Word
|
||||
private Document _document = null;
|
||||
|
||||
// Хранит тело документа Word
|
||||
private Body _body = null;
|
||||
|
||||
// Список байтовых массивов для изображений
|
||||
private List<byte[]> _images = null;
|
||||
|
||||
// Свойство для получения или создания документа Word
|
||||
private Document Document
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_document == null)
|
||||
{
|
||||
_document = new Document();
|
||||
}
|
||||
|
||||
return _document;
|
||||
}
|
||||
}
|
||||
|
||||
// Свойство для получения или создания тела документа Word
|
||||
private Body Body
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_body == null)
|
||||
{
|
||||
_body = Document.AppendChild(new Body());
|
||||
}
|
||||
|
||||
return _body;
|
||||
}
|
||||
}
|
||||
|
||||
// Свойство для получения списка изображений
|
||||
private List<byte[]> Images
|
||||
{
|
||||
get
|
||||
{
|
||||
// Если список изображений еще не создан, инициализируем его
|
||||
if (_images == null)
|
||||
{
|
||||
_images = new List<byte[]>();
|
||||
}
|
||||
|
||||
return _images;
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateHeader(string header)
|
||||
{
|
||||
DocumentFormat.OpenXml.Wordprocessing.Paragraph paragraph = Body.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Paragraph());
|
||||
DocumentFormat.OpenXml.Wordprocessing.Run run = paragraph.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Run());
|
||||
run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.RunProperties(new Bold()));
|
||||
run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text(header));
|
||||
}
|
||||
|
||||
public void CreateImage(byte[] image)
|
||||
{
|
||||
if (image == null || image.Length == 0)
|
||||
{
|
||||
throw new ArgumentNullException("Картинка не загружена");
|
||||
}
|
||||
|
||||
Images.Add(image);
|
||||
}
|
||||
|
||||
public void SaveDoc(string filepath)
|
||||
{
|
||||
if (filepath.IsEmpty())
|
||||
{
|
||||
throw new ArgumentNullException("Имя файла не задано");
|
||||
}
|
||||
|
||||
if (_document == null || _body == null)
|
||||
{
|
||||
throw new ArgumentNullException("Документ не сформирован, сохранять нечего");
|
||||
}
|
||||
|
||||
using WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Create(filepath, WordprocessingDocumentType.Document);
|
||||
MainDocumentPart mainDocumentPart = wordprocessingDocument.AddMainDocumentPart();
|
||||
mainDocumentPart.Document = Document;
|
||||
if (_images != null)
|
||||
{
|
||||
int num = 0;
|
||||
foreach (byte[] image in _images)
|
||||
{
|
||||
ImagePart imagePart = mainDocumentPart.AddImagePart(ImagePartType.Jpeg);
|
||||
using (MemoryStream memoryStream = new MemoryStream(image))
|
||||
{
|
||||
memoryStream.Position = 0L;
|
||||
imagePart.FeedData(memoryStream);
|
||||
}
|
||||
|
||||
AddImageToBody(mainDocumentPart.GetIdOfPart(imagePart), ++num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddImageToBody(string relationshipId, int index)
|
||||
{
|
||||
OpenXmlElement[] array = new OpenXmlElement[1];
|
||||
OpenXmlElement[] obj = new OpenXmlElement[5]
|
||||
{
|
||||
new Extent
|
||||
{
|
||||
Cx = (Int64Value)3000000L,
|
||||
Cy = (Int64Value)3000000L
|
||||
},
|
||||
new EffectExtent
|
||||
{
|
||||
LeftEdge = (Int64Value)0L,
|
||||
TopEdge = (Int64Value)0L,
|
||||
RightEdge = (Int64Value)0L,
|
||||
BottomEdge = (Int64Value)0L
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null
|
||||
};
|
||||
DocProperties obj2 = new DocProperties
|
||||
{
|
||||
Id = (UInt32Value)1u
|
||||
};
|
||||
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(8, 1);
|
||||
defaultInterpolatedStringHandler.AppendLiteral("Picture ");
|
||||
defaultInterpolatedStringHandler.AppendFormatted(index);
|
||||
obj2.Name = (StringValue)defaultInterpolatedStringHandler.ToStringAndClear();
|
||||
obj[2] = obj2;
|
||||
obj[3] = new DocumentFormat.OpenXml.Drawing.Wordprocessing.NonVisualGraphicFrameDrawingProperties(new GraphicFrameLocks
|
||||
{
|
||||
NoChangeAspect = (BooleanValue)true
|
||||
});
|
||||
OpenXmlElement[] array2 = new OpenXmlElement[1];
|
||||
OpenXmlElement[] array3 = new OpenXmlElement[1];
|
||||
OpenXmlElement[] array4 = new OpenXmlElement[3];
|
||||
OpenXmlElement[] array5 = new OpenXmlElement[2];
|
||||
DocumentFormat.OpenXml.Drawing.Pictures.NonVisualDrawingProperties obj3 = new DocumentFormat.OpenXml.Drawing.Pictures.NonVisualDrawingProperties
|
||||
{
|
||||
Id = (UInt32Value)0u
|
||||
};
|
||||
defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(16, 1);
|
||||
defaultInterpolatedStringHandler.AppendLiteral("New Picture ");
|
||||
defaultInterpolatedStringHandler.AppendFormatted(index);
|
||||
defaultInterpolatedStringHandler.AppendLiteral(".jpg");
|
||||
obj3.Name = (StringValue)defaultInterpolatedStringHandler.ToStringAndClear();
|
||||
array5[0] = obj3;
|
||||
array5[1] = new DocumentFormat.OpenXml.Drawing.Pictures.NonVisualPictureDrawingProperties();
|
||||
array4[0] = new DocumentFormat.OpenXml.Drawing.Pictures.NonVisualPictureProperties(array5);
|
||||
array4[1] = new DocumentFormat.OpenXml.Drawing.Pictures.BlipFill(new Blip(new BlipExtensionList(new BlipExtension
|
||||
{
|
||||
Uri = (StringValue)"{28A0092B-C50C-407E-A947-70E740481C1C}"
|
||||
}))
|
||||
{
|
||||
Embed = (StringValue)relationshipId,
|
||||
CompressionState = (EnumValue<BlipCompressionValues>)BlipCompressionValues.Print
|
||||
}, new Stretch(new FillRectangle()));
|
||||
array4[2] = new DocumentFormat.OpenXml.Drawing.Pictures.ShapeProperties(new Transform2D(new Offset
|
||||
{
|
||||
X = (Int64Value)0L,
|
||||
Y = (Int64Value)0L
|
||||
}, new Extents
|
||||
{
|
||||
Cx = (Int64Value)990000L,
|
||||
Cy = (Int64Value)792000L
|
||||
}), new PresetGeometry(new AdjustValueList())
|
||||
{
|
||||
Preset = (EnumValue<ShapeTypeValues>)ShapeTypeValues.Rectangle
|
||||
});
|
||||
array3[0] = new DocumentFormat.OpenXml.Drawing.Pictures.Picture(array4);
|
||||
array2[0] = new GraphicData(array3)
|
||||
{
|
||||
Uri = (StringValue)"http://schemas.openxmlformats.org/drawingml/2006/picture"
|
||||
};
|
||||
obj[4] = new Graphic(array2);
|
||||
array[0] = new Inline(obj)
|
||||
{
|
||||
DistanceFromTop = (UInt32Value)0u,
|
||||
DistanceFromBottom = (UInt32Value)0u,
|
||||
DistanceFromLeft = (UInt32Value)0u,
|
||||
DistanceFromRight = (UInt32Value)0u,
|
||||
EditId = (HexBinaryValue)"50D07946"
|
||||
};
|
||||
|
||||
Drawing drawing = new Drawing(array);
|
||||
Body.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Paragraph(new DocumentFormat.OpenXml.Wordprocessing.Run(drawing)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
288
Lab 2/Belianin_2/MyCustomComponents/Helpers/TableService.cs
Normal file
288
Lab 2/Belianin_2/MyCustomComponents/Helpers/TableService.cs
Normal file
@ -0,0 +1,288 @@
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
using DocumentFormat.OpenXml.Drawing;
|
||||
using DocumentFormat.OpenXml;
|
||||
using MyCustomComponents.Helpers;
|
||||
using MyCustomComponents.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyCustomComponents.Helpers
|
||||
{
|
||||
public class TableService
|
||||
{
|
||||
private Document _document = null;
|
||||
|
||||
private Body _body = null;
|
||||
|
||||
private DocumentFormat.OpenXml.Wordprocessing.Table _table = null;
|
||||
|
||||
// Свойство для создания или получения документа
|
||||
private Document Document
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_document == null)
|
||||
{
|
||||
_document = new Document();
|
||||
}
|
||||
|
||||
return _document;
|
||||
}
|
||||
}
|
||||
|
||||
// Свойство для создания или получения содержимого (Body) документа
|
||||
private Body Body
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_body == null)
|
||||
{
|
||||
_body = Document.AppendChild(new Body());
|
||||
}
|
||||
|
||||
return _body;
|
||||
}
|
||||
}
|
||||
|
||||
// Свойство для создания или получения таблицы
|
||||
private DocumentFormat.OpenXml.Wordprocessing.Table Table
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_table == null)
|
||||
{
|
||||
_table = new DocumentFormat.OpenXml.Wordprocessing.Table();
|
||||
}
|
||||
|
||||
return _table;
|
||||
}
|
||||
}
|
||||
|
||||
// Метод для сохранения документа
|
||||
public void SaveDoc(string filepath)
|
||||
{
|
||||
if (filepath.IsEmpty())
|
||||
{
|
||||
throw new ArgumentNullException("Имя файла не задано");
|
||||
}
|
||||
|
||||
if (_document == null || _body == null)
|
||||
{
|
||||
throw new ArgumentNullException("Документ не сформирован, сохранять нечего");
|
||||
}
|
||||
|
||||
if (_table != null)
|
||||
{
|
||||
Body.Append(Table);
|
||||
}
|
||||
|
||||
using WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Create(filepath, WordprocessingDocumentType.Document);
|
||||
MainDocumentPart mainDocumentPart = wordprocessingDocument.AddMainDocumentPart();
|
||||
mainDocumentPart.Document = Document;
|
||||
|
||||
}
|
||||
|
||||
// Метод для загрузки данных в таблицу
|
||||
public void LoadDataToTableWithColumnHeader(string[,] data)
|
||||
{
|
||||
for (int i = 0; i < data.GetLength(0); i++)
|
||||
{
|
||||
DocumentFormat.OpenXml.Wordprocessing.TableRow tableRow = Table.Elements<DocumentFormat.OpenXml.Wordprocessing.TableRow>().ElementAt(i);
|
||||
|
||||
for (int j = 0; j < data.GetLength(1); j++)
|
||||
{
|
||||
DocumentFormat.OpenXml.Wordprocessing.TableCell tableCell = new DocumentFormat.OpenXml.Wordprocessing.TableCell();
|
||||
tableCell.Append(new DocumentFormat.OpenXml.Wordprocessing.Paragraph(new DocumentFormat.OpenXml.Wordprocessing.Run(new DocumentFormat.OpenXml.Wordprocessing.Text(data[i, j]))));
|
||||
tableRow.Append(tableCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Метод для добавления заголовка с объединением колонок
|
||||
private void AddColumnHeaderCellMergeByCols(string header, int rowHeight)
|
||||
{
|
||||
DocumentFormat.OpenXml.Wordprocessing.TableRow tableRow = new DocumentFormat.OpenXml.Wordprocessing.TableRow();
|
||||
int? rowHeight2 = rowHeight;
|
||||
|
||||
DocumentFormat.OpenXml.Wordprocessing.TableCell tableCell = CreateCell(header, null, rowHeight2);
|
||||
tableCell.Append(new HorizontalMerge
|
||||
{
|
||||
Val = (EnumValue<MergedCellValues>)MergedCellValues.Restart
|
||||
});
|
||||
|
||||
tableRow.Append(tableCell);
|
||||
tableCell = new DocumentFormat.OpenXml.Wordprocessing.TableCell(new DocumentFormat.OpenXml.Wordprocessing.Paragraph());
|
||||
tableCell.Append(new HorizontalMerge
|
||||
{
|
||||
Val = (EnumValue<MergedCellValues>)MergedCellValues.Continue
|
||||
});
|
||||
|
||||
tableRow.Append(tableCell);
|
||||
Table.Append(tableRow);
|
||||
}
|
||||
|
||||
// Метод для создания ячейки таблицы
|
||||
private static DocumentFormat.OpenXml.Wordprocessing.TableCell CreateCell(string header, int? columnWidth = null, int? rowHeight = null)
|
||||
{
|
||||
DocumentFormat.OpenXml.Wordprocessing.TableCell tableCell = new DocumentFormat.OpenXml.Wordprocessing.TableCell();
|
||||
DocumentFormat.OpenXml.Wordprocessing.TableCellProperties tableCellProperties = new DocumentFormat.OpenXml.Wordprocessing.TableCellProperties();
|
||||
|
||||
// Задание высоты строки, если указана
|
||||
if (rowHeight.HasValue)
|
||||
{
|
||||
tableCellProperties.Append(new TableRowHeight
|
||||
{
|
||||
Val = (UInt32Value)Convert.ToUInt32(rowHeight)
|
||||
});
|
||||
}
|
||||
|
||||
// Задание ширины колонки, если указана
|
||||
if (columnWidth.HasValue)
|
||||
{
|
||||
tableCellProperties.Append(new TableCellWidth
|
||||
{
|
||||
Width = (StringValue)columnWidth.Value.ToString()
|
||||
});
|
||||
}
|
||||
|
||||
tableCellProperties.Append(new TableCellVerticalAlignment
|
||||
{
|
||||
Val = (EnumValue<TableVerticalAlignmentValues>)TableVerticalAlignmentValues.Center
|
||||
});
|
||||
|
||||
tableCell.Append(tableCellProperties);
|
||||
DocumentFormat.OpenXml.Wordprocessing.Paragraph paragraph = new DocumentFormat.OpenXml.Wordprocessing.Paragraph();
|
||||
DocumentFormat.OpenXml.Wordprocessing.ParagraphProperties paragraphProperties = new DocumentFormat.OpenXml.Wordprocessing.ParagraphProperties();
|
||||
|
||||
paragraphProperties.Append(new Justification
|
||||
{
|
||||
Val = (EnumValue<JustificationValues>)JustificationValues.Center
|
||||
});
|
||||
|
||||
paragraph.Append(paragraphProperties);
|
||||
|
||||
if (header.HaveText())
|
||||
{
|
||||
DocumentFormat.OpenXml.Wordprocessing.Run run = new DocumentFormat.OpenXml.Wordprocessing.Run();
|
||||
run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.RunProperties(new Bold()));
|
||||
run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text(header));
|
||||
paragraph.Append(run);
|
||||
}
|
||||
|
||||
tableCell.Append(paragraph);
|
||||
return tableCell;
|
||||
}
|
||||
|
||||
// Метод для создания заголовков колонок
|
||||
public void CreateColumnHeader(WordWithTableConfig config)
|
||||
{
|
||||
// Логика создания заголовков таблицы с объединением ячеек
|
||||
int k;
|
||||
for (k = 0; k < config.ColumnUnion[0].StartIndex; k++)
|
||||
{
|
||||
AddColumnHeaderCellMergeByCols(config.Headers.FirstOrDefault<(int, int, string, string)>(((int ColumnIndex, int RowIndex, string Header, string PropertyName) x) => x.ColumnIndex == k).Item3, config.ColumnsRowsWidth[k].Row);
|
||||
}
|
||||
|
||||
int j;
|
||||
for (j = 0; j < config.ColumnUnion.Count; j++)
|
||||
{
|
||||
int l;
|
||||
for (l = config.ColumnUnion[j].StartIndex; l < config.ColumnUnion[j].StartIndex + config.ColumnUnion[j].Count; l++)
|
||||
{
|
||||
DocumentFormat.OpenXml.Wordprocessing.TableRow tableRow = new DocumentFormat.OpenXml.Wordprocessing.TableRow();
|
||||
|
||||
if (l == config.ColumnUnion[j].StartIndex)
|
||||
{
|
||||
DocumentFormat.OpenXml.Wordprocessing.TableCell tableCell = CreateCell(config.Headers.FirstOrDefault<(int, int, string, string)>(((int ColumnIndex, int RowIndex, string Header, string PropertyName) x) => x.ColumnIndex == l && x.RowIndex == 0).Item3);
|
||||
|
||||
tableCell.Append(new VerticalMerge
|
||||
{
|
||||
Val = (EnumValue<MergedCellValues>)MergedCellValues.Restart
|
||||
});
|
||||
|
||||
tableRow.Append(tableCell);
|
||||
}
|
||||
else
|
||||
{
|
||||
DocumentFormat.OpenXml.Wordprocessing.TableCell tableCell2 = new DocumentFormat.OpenXml.Wordprocessing.TableCell(new DocumentFormat.OpenXml.Wordprocessing.Paragraph());
|
||||
|
||||
tableCell2.Append(new VerticalMerge
|
||||
{
|
||||
Val = (EnumValue<MergedCellValues>)MergedCellValues.Continue
|
||||
});
|
||||
|
||||
tableRow.Append(tableCell2);
|
||||
}
|
||||
|
||||
OpenXmlElement[] array = new OpenXmlElement[1];
|
||||
string item = config.Headers.FirstOrDefault<(int, int, string, string)>(((int ColumnIndex, int RowIndex, string Header, string PropertyName) x) => x.ColumnIndex == l && x.RowIndex == 1).Item3;
|
||||
int? rowHeight = config.ColumnsRowsWidth[l].Row;
|
||||
|
||||
array[0] = CreateCell(item, null, rowHeight);
|
||||
tableRow.Append(array);
|
||||
Table.Append(tableRow);
|
||||
}
|
||||
|
||||
if (j >= config.ColumnUnion.Count - 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int m = config.ColumnUnion[j].StartIndex + config.ColumnUnion[j].Count; m < config.ColumnUnion[j + 1].StartIndex; m++)
|
||||
{
|
||||
AddColumnHeaderCellMergeByCols(config.Headers.FirstOrDefault<(int, int, string, string)>(((int ColumnIndex, int RowIndex, string Header, string PropertyName) x) => x.ColumnIndex == j).Item3, config.ColumnsRowsWidth[j].Row);
|
||||
}
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = config.ColumnUnion[config.ColumnUnion.Count - 1].StartIndex + config.ColumnUnion[config.ColumnUnion.Count - 1].Count; i < config.ColumnsRowsWidth.Count; i++)
|
||||
{
|
||||
AddColumnHeaderCellMergeByCols(config.Headers.FirstOrDefault<(int, int, string, string)>(((int ColumnIndex, int RowIndex, string Header, string PropertyName) x) => x.ColumnIndex == i).Item3, config.ColumnsRowsWidth[i].Row);
|
||||
}
|
||||
}
|
||||
|
||||
// Метод для создания таблицы с заголовком
|
||||
public void CreateTableWithHeader()
|
||||
{
|
||||
Table.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.TableProperties(new TableBorders(new DocumentFormat.OpenXml.Wordprocessing.TopBorder
|
||||
{
|
||||
Val = new EnumValue<BorderValues>(BorderValues.Single),
|
||||
Size = (UInt32Value)12u
|
||||
}, new DocumentFormat.OpenXml.Wordprocessing.BottomBorder
|
||||
{
|
||||
Val = new EnumValue<BorderValues>(BorderValues.Single),
|
||||
Size = (UInt32Value)12u
|
||||
}, new DocumentFormat.OpenXml.Wordprocessing.LeftBorder
|
||||
{
|
||||
Val = new EnumValue<BorderValues>(BorderValues.Single),
|
||||
Size = (UInt32Value)12u
|
||||
}, new DocumentFormat.OpenXml.Wordprocessing.RightBorder
|
||||
{
|
||||
Val = new EnumValue<BorderValues>(BorderValues.Single),
|
||||
Size = (UInt32Value)12u
|
||||
}, new DocumentFormat.OpenXml.Wordprocessing.InsideHorizontalBorder
|
||||
{
|
||||
Val = new EnumValue<BorderValues>(BorderValues.Single),
|
||||
Size = (UInt32Value)12u
|
||||
}, new DocumentFormat.OpenXml.Wordprocessing.InsideVerticalBorder
|
||||
{
|
||||
Val = new EnumValue<BorderValues>(BorderValues.Single),
|
||||
Size = (UInt32Value)12u
|
||||
})));
|
||||
}
|
||||
|
||||
// Метод для создания заголовка документа
|
||||
public void CreateHeader(string header)
|
||||
{
|
||||
DocumentFormat.OpenXml.Wordprocessing.Paragraph paragraph = Body.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Paragraph());
|
||||
DocumentFormat.OpenXml.Wordprocessing.Run run = paragraph.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Run());
|
||||
|
||||
run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.RunProperties(new Bold()));
|
||||
run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text(header));
|
||||
}
|
||||
}
|
||||
}
|
16
Lab 2/Belianin_2/MyCustomComponents/Models/Location.cs
Normal file
16
Lab 2/Belianin_2/MyCustomComponents/Models/Location.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyCustomComponents.Models
|
||||
{
|
||||
public enum Location
|
||||
{
|
||||
Left,
|
||||
Right,
|
||||
Top,
|
||||
Bottom
|
||||
}
|
||||
}
|
15
Lab 2/Belianin_2/MyCustomComponents/Models/WordConfig.cs
Normal file
15
Lab 2/Belianin_2/MyCustomComponents/Models/WordConfig.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyCustomComponents.Models
|
||||
{
|
||||
public class WordConfig
|
||||
{
|
||||
public string FilePath { get; set; }
|
||||
|
||||
public string Header { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyCustomComponents.Models
|
||||
{
|
||||
public class WordWithDiagramConfig : WordConfig
|
||||
{
|
||||
public string ChartTitle { get; set; }
|
||||
|
||||
public Location LegendLocation { get; set; }
|
||||
|
||||
public Dictionary<string, List<(int Date, double Value)>> Data { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyCustomComponents.Models
|
||||
{
|
||||
public class WordWithImageConfig : WordConfig
|
||||
{
|
||||
public List<byte[]> Images { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyCustomComponents.Models
|
||||
{
|
||||
public class WordWithTableConfig : WordConfig
|
||||
{
|
||||
public bool UseUnion { get; set; }
|
||||
|
||||
public (int Columns, int Rows) ColumnsRowsDataCount { get; set; }
|
||||
|
||||
public List<(int Column, int Row)> ColumnsRowsWidth { get; set; }
|
||||
|
||||
public List<(int StartIndex, int Count)> ColumnUnion { get; set; }
|
||||
|
||||
public List<(int ColumnIndex, int RowIndex, string Header, string PropertyName)> Headers { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyCustomComponents.Models
|
||||
{
|
||||
public class WordWithTableDataConfig<T> : WordWithTableConfig
|
||||
{
|
||||
public List<T> Data { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DocumentFormat.OpenXml" Version="2.20.0" />
|
||||
<PackageReference Include="Microsoft.Win32.SystemEvents" Version="7.0.0" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
36
Lab 2/Belianin_2/MyCustomComponents/WordWithDiagram.Designer.cs
generated
Normal file
36
Lab 2/Belianin_2/MyCustomComponents/WordWithDiagram.Designer.cs
generated
Normal file
@ -0,0 +1,36 @@
|
||||
namespace MyCustomComponents
|
||||
{
|
||||
partial class WordWithDiagram
|
||||
{
|
||||
/// <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()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
53
Lab 2/Belianin_2/MyCustomComponents/WordWithDiagram.cs
Normal file
53
Lab 2/Belianin_2/MyCustomComponents/WordWithDiagram.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using DocumentFormat.OpenXml.Drawing.Charts;
|
||||
using DocumentFormat.OpenXml.Drawing.Wordprocessing;
|
||||
using DocumentFormat.OpenXml.Drawing;
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml;
|
||||
using MyCustomComponents.Helpers;
|
||||
using MyCustomComponents.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
|
||||
namespace MyCustomComponents
|
||||
{
|
||||
public partial class WordWithDiagram : Component
|
||||
{
|
||||
private DiagramService creator;
|
||||
|
||||
// Конструктор по умолчанию
|
||||
public WordWithDiagram()
|
||||
{
|
||||
InitializeComponent();
|
||||
creator = new DiagramService();
|
||||
}
|
||||
|
||||
// Конструктор с контейнером для компонентов
|
||||
public WordWithDiagram(IContainer container)
|
||||
{
|
||||
container.Add(this);
|
||||
|
||||
InitializeComponent();
|
||||
creator = new DiagramService();
|
||||
}
|
||||
|
||||
public void CreateDoc(WordWithDiagramConfig config)
|
||||
{
|
||||
config.CheckFields();
|
||||
|
||||
// Создание заголовка
|
||||
creator.CreateHeader(config.Header);
|
||||
|
||||
// Создание диаграммы
|
||||
creator.CreatePieChart(config);
|
||||
|
||||
// Сохранение в файл
|
||||
creator.SaveDoc(config.FilePath);
|
||||
}
|
||||
}
|
||||
}
|
36
Lab 2/Belianin_2/MyCustomComponents/WordWithImages.Designer.cs
generated
Normal file
36
Lab 2/Belianin_2/MyCustomComponents/WordWithImages.Designer.cs
generated
Normal file
@ -0,0 +1,36 @@
|
||||
namespace MyCustomComponents
|
||||
{
|
||||
partial class WordWithImages
|
||||
{
|
||||
/// <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()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
59
Lab 2/Belianin_2/MyCustomComponents/WordWithImages.cs
Normal file
59
Lab 2/Belianin_2/MyCustomComponents/WordWithImages.cs
Normal file
@ -0,0 +1,59 @@
|
||||
using DocumentFormat.OpenXml.Drawing.Wordprocessing;
|
||||
using DocumentFormat.OpenXml.Drawing;
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml;
|
||||
using MyCustomComponents.Helpers;
|
||||
using MyCustomComponents.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
using DocumentFormat.OpenXml.Drawing.Charts;
|
||||
using DocumentFormat.OpenXml.Drawing.Diagrams;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MyCustomComponents
|
||||
{
|
||||
public partial class WordWithImages : Component
|
||||
{
|
||||
private ImageService creator;
|
||||
|
||||
// Конструктор по умолчанию
|
||||
public WordWithImages()
|
||||
{
|
||||
InitializeComponent();
|
||||
creator = new ImageService();
|
||||
}
|
||||
|
||||
// Конструктор с контейнером для компонентов
|
||||
public WordWithImages(IContainer container)
|
||||
{
|
||||
container.Add(this);
|
||||
InitializeComponent();
|
||||
creator = new ImageService();
|
||||
}
|
||||
|
||||
// Метод для создания документа Word с изображениями
|
||||
public void CreateDoc(WordWithImageConfig config)
|
||||
{
|
||||
config.CheckFields();
|
||||
|
||||
// Создание заголовка
|
||||
creator.CreateHeader(config.Header);
|
||||
|
||||
// Создание и добавление всех изображений
|
||||
foreach (byte[] image in config.Images)
|
||||
{
|
||||
creator.CreateImage(image);
|
||||
}
|
||||
|
||||
// Сохранение файла
|
||||
creator.SaveDoc(config.FilePath);
|
||||
}
|
||||
}
|
||||
}
|
36
Lab 2/Belianin_2/MyCustomComponents/WordWithTable.Designer.cs
generated
Normal file
36
Lab 2/Belianin_2/MyCustomComponents/WordWithTable.Designer.cs
generated
Normal file
@ -0,0 +1,36 @@
|
||||
namespace MyCustomComponents
|
||||
{
|
||||
partial class WordWithTable
|
||||
{
|
||||
/// <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()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
71
Lab 2/Belianin_2/MyCustomComponents/WordWithTable.cs
Normal file
71
Lab 2/Belianin_2/MyCustomComponents/WordWithTable.cs
Normal file
@ -0,0 +1,71 @@
|
||||
using MyCustomComponents.Helpers;
|
||||
using MyCustomComponents.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MyCustomComponents
|
||||
{
|
||||
public partial class WordWithTable : Component
|
||||
{
|
||||
private TableService creator;
|
||||
|
||||
// Конструктор
|
||||
public WordWithTable()
|
||||
{
|
||||
InitializeComponent();
|
||||
creator = new TableService();
|
||||
}
|
||||
|
||||
// Конструктор с контейнером
|
||||
public WordWithTable(IContainer container)
|
||||
{
|
||||
container.Add(this);
|
||||
|
||||
InitializeComponent();
|
||||
creator = new TableService();
|
||||
}
|
||||
|
||||
// Метод для создания документа с таблицей
|
||||
public void CreateDoc<T>(WordWithTableDataConfig<T> config)
|
||||
{
|
||||
config.CheckFields();
|
||||
config.ColumnsRowsDataCount = (config.Data.Count + 2, config.ColumnsRowsWidth.Count);
|
||||
|
||||
// Создание заголовка
|
||||
creator.CreateHeader(config.Header);
|
||||
|
||||
// Создание таблицы с заголовком
|
||||
creator.CreateTableWithHeader();
|
||||
|
||||
// Создание заголовков столбцов
|
||||
creator.CreateColumnHeader(config);
|
||||
|
||||
// Создание массива данных для таблицы
|
||||
string[,] array = new string[config.ColumnsRowsWidth.Count, config.Data.Count];
|
||||
for (int j = 0; j < config.Data.Count; j++)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < config.ColumnsRowsWidth.Count; i++)
|
||||
{
|
||||
(int, int, string, string) tuple = config.Headers.FirstOrDefault<(int, int, string, string)>(((int ColumnIndex, int RowIndex, string Header, string PropertyName) x) => x.ColumnIndex == i && x.RowIndex == 1);
|
||||
if (tuple.Equals(default((int, int, string, string))))
|
||||
{
|
||||
tuple = config.Headers.FirstOrDefault<(int, int, string, string)>(((int ColumnIndex, int RowIndex, string Header, string PropertyName) x) => x.ColumnIndex == i && x.RowIndex == 0);
|
||||
}
|
||||
|
||||
array[i, j] = config.Data[j].GetType().GetProperty(tuple.Item4)!.GetValue(config.Data[j], null)!.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
// Загрузка данных в таблицу и последующее сохранение документа
|
||||
creator.LoadDataToTableWithColumnHeader(array);
|
||||
creator.SaveDoc(config.FilePath);
|
||||
}
|
||||
}
|
||||
}
|
BIN
Lab 2/WordWithDiagramDocx.docx
Normal file
BIN
Lab 2/WordWithDiagramDocx.docx
Normal file
Binary file not shown.
BIN
Lab 2/WordWithImageDocx.docx
Normal file
BIN
Lab 2/WordWithImageDocx.docx
Normal file
Binary file not shown.
BIN
Lab 2/WordWithTableDocx.docx
Normal file
BIN
Lab 2/WordWithTableDocx.docx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user