Compare commits

...

6 Commits
main ... lab2

Author SHA1 Message Date
DyCTaTOR
3a02a9e7f2 lab2 - сдано 2024-10-15 10:57:48 +04:00
DyCTaTOR
4a3147a908 Merge branch 'lab1' into lab2 2024-10-15 10:29:29 +04:00
DyCTaTOR
86ac64ad42 lab1 - сдано 2024-10-15 10:29:10 +04:00
DyCTaTOR
ff464aea76 lab1 - modifed 2024-10-14 20:12:04 +04:00
DyCTaTOR
bdf15f37cd лаб2 - готово 2024-10-14 19:54:00 +04:00
DyCTaTOR
7bdd5ea8fb lab1 - почти готова 2024-10-14 13:05:17 +04:00
38 changed files with 2234 additions and 0 deletions

View File

@ -0,0 +1,67 @@
using WinFormsLibrary1;
namespace WinFormsApp1
{
partial class Form1
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
comboBoxUserControl = new ComboBox();
listBoxUserControl = new ListBox();
dateInputControl1 = new DateInputControl();
SuspendLayout();
//
// comboBoxUserControl
//
comboBoxUserControl.Location = new Point(13, 15);
comboBoxUserControl.Margin = new Padding(4, 5, 4, 5);
comboBoxUserControl.Name = "comboBoxUserControl";
comboBoxUserControl.Size = new Size(160, 28);
comboBoxUserControl.TabIndex = 0;
//
// listBoxUserControl
//
listBoxUserControl.Location = new Point(13, 231);
listBoxUserControl.Margin = new Padding(4, 5, 4, 5);
listBoxUserControl.Name = "listBoxUserControl";
listBoxUserControl.Size = new Size(159, 144);
listBoxUserControl.TabIndex = 2;
//
// dateInputControl1
//
dateInputControl1.Location = new Point(13, 107);
dateInputControl1.Margin = new Padding(4, 5, 4, 5);
dateInputControl1.Name = "dateInputControl1";
dateInputControl1.Size = new Size(166, 96);
dateInputControl1.TabIndex = 3;
//
// Form1
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(400, 462);
Controls.Add(dateInputControl1);
Controls.Add(listBoxUserControl);
Controls.Add(comboBoxUserControl);
Margin = new Padding(4, 5, 4, 5);
Name = "Form1";
Text = "Form1";
ResumeLayout(false);
}
private ComboBox comboBoxUserControl;
private ListBox listBoxUserControl;
private DateInputControl dateInputControl1;
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Windows.Forms;
using WinFormsLibrary1;
namespace WinFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void ComboBoxUserControl_SelectedValueChanged(object sender, EventArgs e)
{
MessageBox.Show($"ComboBox selected: {comboBoxUserControl.SelectedValue}");
}
private void ListBoxUserControl_SelectedValueChanged(object sender, EventArgs e)
{
MessageBox.Show($"ListBox selected: {listBoxUserControl.SelectedValue}");
}
}
}

View 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>

View File

@ -0,0 +1,81 @@
using WinFormsLibrary1;
namespace WinFormsApp1
{
partial class Form2
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
buttonCreateTextDocument = new Button();
buttonCreateTableDocument = new Button();
buttonCreateDiagramDocument = new Button();
bigTextComponent1 = new ComponentWithBigText(components);
tableComponent1 = new ComponentTable(components);
diagramComponent1 = new ComponentDiagram(components);
SuspendLayout();
//
// buttonCreateTextDocument
//
buttonCreateTextDocument.Location = new Point(12, 30);
buttonCreateTextDocument.Name = "buttonCreateTextDocument";
buttonCreateTextDocument.Size = new Size(125, 50);
buttonCreateTextDocument.TabIndex = 0;
buttonCreateTextDocument.Text = "Создать документ с текстом";
buttonCreateTextDocument.UseVisualStyleBackColor = true;
buttonCreateTextDocument.Click += buttonCreateTextDocument_Click;
//
// buttonCreateTableDocument
//
buttonCreateTableDocument.Location = new Point(180, 30);
buttonCreateTableDocument.Name = "buttonCreateTableDocument";
buttonCreateTableDocument.Size = new Size(125, 50);
buttonCreateTableDocument.TabIndex = 1;
buttonCreateTableDocument.Text = "Создать документ с таблицей";
buttonCreateTableDocument.UseVisualStyleBackColor = true;
buttonCreateTableDocument.Click += buttonCreateTableDocument_Click;
//
// buttonCreateDiagramDocument
//
buttonCreateDiagramDocument.Location = new Point(347, 30);
buttonCreateDiagramDocument.Name = "buttonCreateDiagramDocument";
buttonCreateDiagramDocument.Size = new Size(125, 50);
buttonCreateDiagramDocument.TabIndex = 2;
buttonCreateDiagramDocument.Text = "Создать документ с диаграммой";
buttonCreateDiagramDocument.UseVisualStyleBackColor = true;
buttonCreateDiagramDocument.Click += buttonCreateDiagramDocument_Click;
//
// FormNonVisualComponents
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(484, 111);
Controls.Add(buttonCreateDiagramDocument);
Controls.Add(buttonCreateTableDocument);
Controls.Add(buttonCreateTextDocument);
Name = "FormNonVisualComponents";
Text = "Не визуальные компоненты";
ResumeLayout(false);
}
#endregion
private Button buttonCreateTextDocument;
private Button buttonCreateTableDocument;
private Button buttonCreateDiagramDocument;
private ComponentWithBigText bigTextComponent1;
private ComponentTable tableComponent1;
private ComponentDiagram diagramComponent1;
}
}

View File

@ -0,0 +1,94 @@
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;
using WinFormsLibrary1.Models;
namespace WinFormsApp1
{
public partial class Form2: Form
{
public Form2()
{
InitializeComponent();
}
private void buttonCreateTextDocument_Click(object sender, EventArgs e)
{
string filepath = "C:\\Users\\Владимир\\Desktop\\BigTextDocumentExcel.xlsx";
string title = "Документ с большим текстом";
string[] rows =
{
"Строка1",
"Строка2",
"Строка3",
"Строка4"
};
bigTextComponent1.CreateDocument(filepath, title, rows);
}
private void buttonCreateTableDocument_Click(object sender, EventArgs e)
{
string filepath = "C:\\Users\\Владимир\\Desktop\\TableDocumentExcel.xlsx";
string title = "Документ с таблицей";
List<MergeCell> mergeCells = new List<MergeCell>()
{
new MergeCell("Личные данные", new int[] { 2, 3, 4 }),
};
List<Column> columns = new List<Column>()
{
new Column("Id", "Id", 10),
new Column("Status", "Статус", 10),
new Column("Name", "Имя", 20),
new Column("Familia", "Фамилия", 20),
new Column("Age", "Возраст", 20),
new Column("Department", "Подразделение", 30),
new Column("Salary", "зарплата", 10)
};
List<User> data = new List<User>()
{
new User(1, "нет", "Владимир", "Строев", 34, "Департамент 1", 2000.1),
new User(2, "нет", "Михаил", "Патрушев", 23, "Департамент 2", 192.9),
new User(3, "да", "Евгений", "Борисов", 19, "Департамент 4", 566),
new User(4, "да", "Иван", "Иванов", 41, "Департамент 5", 3990.5),
new User(5, "нет", "Владимир", "Строев", 39, "Департамент 3", 1596.0),
};
tableComponent1.CreateDocument(filepath, title,
mergeCells, columns,
data);
}
private void buttonCreateDiagramDocument_Click(object sender, EventArgs e)
{
LineChartConfig config = new LineChartConfig();
config.Filepath = "C:\\Users\\Владимир\\Desktop\\DiagramDocumentExcel.xlsx";
config.Header = "Документ с диаграммой";
config.ChartTitle = "Моя диаграмма";
string[] charts = { "График 1", "График 2" };
var data = new Dictionary<string, List<int>>();
for (int i = 0; i < 2; i++)
{
var row = new List<int>();
for (var j = 0; j < 5; j++)
{
row.Add(5 * i + j + 1);
}
data.Add(charts[i], row);
}
config.Values = data;
config.LegendPosition = LegendPosition.Bottom;
diagramComponent1.CreateDocument(config);
}
}
}

View 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>

View File

@ -0,0 +1,17 @@
namespace WinFormsApp1
{
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 Form2());
}
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinFormsApp1
{
internal class User
{
public int Id { get; set; }
public string Status { get; set; }
public string Name { get; set; }
public string Familia { get; set; }
public int Age { get; set; }
public string Department { get; set; }
public double Salary { get; set; }
public User() { }
public User(int id, string status, string name, string familia, int age, string department, double salary)
{
Id = id;
Status = status;
Name = name;
Familia = familia;
Age = age;
Department = department;
Salary = salary;
}
}
}

View File

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\WinFormsLibrary1\WinFormsLibrary1.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.34916.146
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinFormsLibrary1", "WinFormsLibrary1\WinFormsLibrary1.csproj", "{4F13F436-1BE0-4F8D-A720-FCBF3893BA55}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinFormsApp1", "WinFormsApp1\WinFormsApp1.csproj", "{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4F13F436-1BE0-4F8D-A720-FCBF3893BA55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4F13F436-1BE0-4F8D-A720-FCBF3893BA55}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F13F436-1BE0-4F8D-A720-FCBF3893BA55}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4F13F436-1BE0-4F8D-A720-FCBF3893BA55}.Release|Any CPU.Build.0 = Release|Any CPU
{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {30BE3CA4-B770-4A5A-A07E-FE2B703C6B13}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,42 @@
namespace WinFormsLibrary1
{
partial class ComboBoxUserControl
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.comboBox = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// comboBox
//
this.comboBox.FormattingEnabled = true;
this.comboBox.Location = new System.Drawing.Point(0, 0);
this.comboBox.Name = "comboBox";
this.comboBox.Size = new System.Drawing.Size(121, 21);
this.comboBox.TabIndex = 0;
this.comboBox.SelectedIndexChanged += new System.EventHandler(this.comboBox_SelectedIndexChanged);
//
// ComboBoxUserControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.comboBox);
this.Name = "ComboBoxUserControl";
this.Size = new System.Drawing.Size(121, 21);
this.ResumeLayout(false);
}
private System.Windows.Forms.ComboBox comboBox;
}
}

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace WinFormsLibrary1
{
public partial class ComboBoxUserControl : UserControl
{
public ComboBoxUserControl()
{
InitializeComponent();
}
public event EventHandler SelectedValueChanged;
public void AddItem(string item)
{
comboBox.Items.Add(item);
}
public void ClearItems()
{
comboBox.Items.Clear();
}
public string SelectedValue
{
get => comboBox.SelectedItem?.ToString() ?? string.Empty;
set => comboBox.SelectedItem = value;
}
private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
SelectedValueChanged?.Invoke(this, e);
}
}
}

View 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>

View File

@ -0,0 +1,36 @@
namespace WinFormsLibrary1
{
partial class ComponentDiagram
{
/// <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
}
}

View File

@ -0,0 +1,123 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using WinFormsLibrary1.Models;
using Excel = Microsoft.Office.Interop.Excel;
namespace WinFormsLibrary1
{
public partial class ComponentDiagram: Component
{
public ComponentDiagram()
{
InitializeComponent();
}
public ComponentDiagram(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public void CreateDocument(LineChartConfig config)
{
if (config == null)
{
throw new ArgumentNullException("Не задана конфигурация для построения линйеной диаграммы!");
}
if (string.IsNullOrEmpty(config.Filepath))
{
throw new ArgumentNullException("Не указан путь к файлу!");
}
if (string.IsNullOrEmpty(config.Header))
{
throw new ArgumentNullException("Не указан заголовок документа!");
}
if (string.IsNullOrEmpty(config.ChartTitle))
{
throw new ArgumentNullException("Не указано название диаграммы!");
}
if (config.Values == null || config.Values.Count == 0)
{
throw new ArgumentNullException("Не заданы значения для отображения на диаграмме!");
}
Excel.Application excelApp = new Excel.Application();
Excel.Workbook workbook = excelApp.Workbooks.Add();
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Sheets[1];
worksheet.Cells[1, 1] = config.Header;
// Создание диаграммы
Excel.ChartObjects chartObjs = (Excel.ChartObjects)worksheet.ChartObjects();
Excel.ChartObject chartObj = chartObjs.Add(5, 50, 300, 300);
Excel.Chart excelChart = chartObj.Chart;
excelChart.ChartType = Excel.XlChartType.xlLine;
// Запись данных
Excel.Range[] valuesRange = new Excel.Range[config.Values.Count];
int leftTopI = 2, leftTopJ = 1;
for (int i = 0; i < config.Values.Count; i++)
{
string key = config.Values.Keys.ToList()[i];
for (int j = 0; j < config.Values[key].Count; j++)
{
worksheet.Cells[leftTopI + i, leftTopJ + j] = config.Values[key][j];
}
valuesRange[i] = worksheet.Range
[worksheet.Cells[leftTopI + i, leftTopJ],
worksheet.Cells[leftTopI + i, leftTopJ + config.Values[key].Count - 1]];
}
// Задание данных
Excel.SeriesCollection seriesCollection = (Excel.SeriesCollection)excelChart.SeriesCollection();
for (int i = 0; i < config.Values.Keys.Count; i++)
{
Excel.Series series = seriesCollection.NewSeries();
series.Name = config.Values.Keys.ToList()[i];
series.Values = valuesRange[i];
}
// Задание заголовка
excelChart.HasTitle = true;
excelChart.ChartTitle.Text = config.ChartTitle;
// Задание легенды
excelChart.HasLegend = true;
switch (config.LegendPosition)
{
case LegendPosition.Top:
excelChart.Legend.Position = Excel.XlLegendPosition.xlLegendPositionTop;
break;
case LegendPosition.Right:
excelChart.Legend.Position = Excel.XlLegendPosition.xlLegendPositionRight;
break;
case LegendPosition.Bottom:
excelChart.Legend.Position = Excel.XlLegendPosition.xlLegendPositionBottom;
break;
case LegendPosition.Left:
excelChart.Legend.Position = Excel.XlLegendPosition.xlLegendPositionLeft;
break;
default:
excelChart.Legend.Position = Excel.XlLegendPosition.xlLegendPositionBottom;
break;
}
if (File.Exists(config.Filepath))
{
File.Delete(config.Filepath);
}
excelApp.Application.ActiveWorkbook.SaveAs(config.Filepath);
workbook.Close(true);
excelApp.Quit();
Marshal.ReleaseComObject(excelApp);
}
}
}

View File

@ -0,0 +1,36 @@
namespace WinFormsLibrary1
{
partial class ComponentTable
{
/// <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
}
}

View File

@ -0,0 +1,162 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using WinFormsLibrary1.Models;
using Excel = Microsoft.Office.Interop.Excel;
namespace WinFormsLibrary1
{
public partial class ComponentTable : Component
{
private char[] _columnIndexes = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
public ComponentTable()
{
InitializeComponent();
}
public ComponentTable(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public void CreateDocument<T>(string filepath, string title,
List<MergeCell> mergeCells, List<Column> columns,
List<T> data) where T : class, new()
{
if (string.IsNullOrEmpty(filepath))
{
throw new ArgumentNullException("Не указан путь к файлу!");
}
if (string.IsNullOrEmpty(title))
{
throw new ArgumentNullException("Не указан заголовок документа!");
}
if (mergeCells == null || mergeCells.Count == 0 || columns == null || columns.Count == 0)
{
throw new ArgumentNullException("Не заполнена информация по колонкам!");
}
if (data == null)
{
throw new ArgumentNullException("Данные не заполнены!");
}
Excel.Application excelApp = new Excel.Application();
Excel.Workbook workbook = excelApp.Workbooks.Add();
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Sheets[1];
worksheet.Cells[1, 1] = title;
// Заголовки таблицы
for (int i = 1; i <= columns.Count; i++)
{
if (string.IsNullOrEmpty(columns[i - 1].Header))
{
throw new Exception("Заголовок не имеет данных!");
}
worksheet.Cells[2, i] = columns[i - 1].Header;
Excel.Range column = (Excel.Range)worksheet.Columns[i];
column.ColumnWidth = columns[i - 1].Width;
Excel.Range cell = (Excel.Range)worksheet.Cells[2, i];
cell.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
cell.VerticalAlignment = Excel.XlHAlign.xlHAlignGeneral;
cell.Font.Bold = true;
}
// Объединение ячеек по столбцам
List<int> mergeIndexes = new List<int>();
foreach (var merge in mergeCells)
{
mergeIndexes.AddRange(merge.CellIndexes);
Excel.Range rangeToCopy = worksheet.get_Range($"{_columnIndexes[merge.CellIndexes[0]]}2", $"{_columnIndexes[merge.CellIndexes[merge.CellIndexes.Length - 1]]}2").Cells;
Excel.Range rangeToInsert = worksheet.get_Range($"{_columnIndexes[merge.CellIndexes[0]]}3", $"{_columnIndexes[merge.CellIndexes[merge.CellIndexes.Length - 1]]}3").Cells;
rangeToInsert.Insert(Excel.XlInsertShiftDirection.xlShiftToRight, rangeToCopy.Cut());
Excel.Range rangeMerge = worksheet.get_Range($"{_columnIndexes[merge.CellIndexes[0]]}2", $"{_columnIndexes[merge.CellIndexes[merge.CellIndexes.Length - 1]]}2").Cells;
rangeMerge.Merge();
worksheet.Cells[2, merge.CellIndexes[0] + 1] = merge.Header;
Excel.Range cell = (Excel.Range)worksheet.Cells[2, merge.CellIndexes[0] + 1];
cell.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
cell.VerticalAlignment = Excel.XlHAlign.xlHAlignCenter;
cell.Font.Bold = true;
}
// Объединение ячеек по строкам, которые не объединяются по столбцам
for (int i = 1; i <= columns.Count; i++)
{
if (!mergeIndexes.Contains(i - 1))
{
Excel.Range range = worksheet.get_Range($"{_columnIndexes[i - 1]}2", $"{_columnIndexes[i - 1]}3").Cells;
range.Merge();
}
}
// Заполнение данных
int row = 4;
foreach (var item in data)
{
var properties = item.GetType().GetProperties();
if (properties.Count() != columns.Count)
{
throw new Exception("Количество полей объекта не соответствует количеству столбцов в таблице!");
}
for (int i = 0; i < properties.Count(); i++)
{
int columnIndex = 0;
var property = properties[i];
var propertyValue = property.GetValue(item);
if (propertyValue == null)
{
throw new Exception("Поле имеет пустое значение!");
}
foreach (var column in columns)
{
if (column.FieldName == property.Name)
{
columnIndex = columns.IndexOf(column) + 1;
break;
}
}
if (columnIndex != 0)
{
worksheet.Cells[row, columnIndex] = propertyValue;
}
}
row++;
}
// Границы таблицы
for (int i = 2; i <= (data.Count() + 3); i++)
{
for (int j = 1; j <= columns.Count(); j++)
{
Excel.Range cell = (Excel.Range)worksheet.Cells[i, j];
cell.BorderAround(true);
}
}
if (File.Exists(filepath))
{
File.Delete(filepath);
}
excelApp.Application.ActiveWorkbook.SaveAs(filepath);
workbook.Close(true);
excelApp.Quit();
Marshal.ReleaseComObject(excelApp);
}
}
}

View File

@ -0,0 +1,24 @@
namespace WinFormsLibrary1
{
partial class ComponentWithBigText
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;
namespace WinFormsLibrary1
{
public partial class ComponentWithBigText : Component
{
public ComponentWithBigText()
{
InitializeComponent();
}
public ComponentWithBigText(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public void CreateDocument(string filepath, string title, string[] rows)
{
if (string.IsNullOrEmpty(filepath))
{
throw new ArgumentNullException("Не указан путь к файлу!");
}
if (string.IsNullOrEmpty(title))
{
throw new ArgumentNullException("Не указан заголовок документа!");
}
if (rows == null || rows.Length == 0)
{
throw new ArgumentNullException("Массив с текстом не заполнен!");
}
Excel.Application excelApp = new Excel.Application();
Excel.Workbook workbook = excelApp.Workbooks.Add();
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Sheets[1];
worksheet.Cells[1, 1] = title;
for (int index = 0; index < rows.Length; index++)
{
worksheet.Cells[index + 3, 1] = rows[index];
}
if (File.Exists(filepath))
{
File.Delete(filepath);
}
excelApp.Application.ActiveWorkbook.SaveAs(filepath);
workbook.Close(true);
excelApp.Quit();
Marshal.ReleaseComObject(excelApp);
}
}
}

View File

@ -0,0 +1,58 @@
namespace WinFormsLibrary1
{
partial class DateInputControl
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
textBoxDate = new TextBox();
errorLabel = new Label();
SuspendLayout();
//
// textBoxDate
//
textBoxDate.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
textBoxDate.Location = new Point(0, 0);
textBoxDate.Margin = new Padding(4, 5, 4, 5);
textBoxDate.Name = "textBoxDate";
textBoxDate.Size = new Size(146, 27);
textBoxDate.TabIndex = 0;
//
// errorLabel
//
errorLabel.AutoSize = true;
errorLabel.ForeColor = Color.Red;
errorLabel.Location = new Point(0, 38);
errorLabel.Margin = new Padding(4, 0, 4, 0);
errorLabel.Name = "errorLabel";
errorLabel.Size = new Size(0, 20);
errorLabel.TabIndex = 1;
errorLabel.Visible = false;
//
// DateInputControl
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(errorLabel);
Controls.Add(textBoxDate);
Margin = new Padding(4, 5, 4, 5);
Name = "DateInputControl";
Size = new Size(149, 88);
ResumeLayout(false);
PerformLayout();
}
private System.Windows.Forms.TextBox textBoxDate;
private System.Windows.Forms.Label errorLabel;
}
}

View File

@ -0,0 +1,68 @@
using System.Globalization;
namespace WinFormsLibrary1
{
public partial class DateInputControl : UserControl
{
private string DateFormat{ get; set; }
public DateInputControl()
{
InitializeComponent();
}
public DateTime Date
{
get
{
if(string.IsNullOrEmpty(textBoxDate.Text))
{
throw new Exception("Введите дату");
}
else if(string.IsNullOrEmpty(DateFormat))
{
throw new Exception("Шаблон не задан");
}
else if (Validate())
{
DateTime parsedDate;
if (DateTime.TryParseExact(textBoxDate.Text, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate))
{
return parsedDate;
}
}
throw new Exception("Неправильно введена дата");
}
set
{
if (string.IsNullOrEmpty(DateFormat))
{
textBoxDate.Text = value.ToString(DateFormat);
}
textBoxDate.Text = string.Empty;
}
}
private void TextBoxDate_TextChanged(object sender, EventArgs e)
{
ValidateDate();
}
private bool ValidateDate()
{
DateTime parsedDate;
if (DateTime.TryParseExact(textBoxDate.Text, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate))
{
errorLabel.Visible = false;
return true;
}
else
{
errorLabel.Visible = true;
errorLabel.Text = $"Неверный формат даты. Используйте формат {DateFormat}.";
return false;
}
}
}
}

View 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>

View File

@ -0,0 +1,42 @@
namespace WinFormsLibrary1
{
partial class ListBoxUserControl
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.listBox = new System.Windows.Forms.ListBox();
this.SuspendLayout();
//
// listBox
//
this.listBox.FormattingEnabled = true;
this.listBox.Location = new System.Drawing.Point(0, 0);
this.listBox.Name = "listBox";
this.listBox.Size = new System.Drawing.Size(120, 95);
this.listBox.TabIndex = 0;
//this.listBox.SelectedIndexChanged += new System.EventHandler(this.listBox_SelectedIndexChanged);
//
// ListBoxUserControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.listBox);
this.Name = "ListBoxUserControl";
this.Size = new System.Drawing.Size(120, 95);
this.ResumeLayout(false);
}
private System.Windows.Forms.ListBox listBox;
}
}

View File

@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace WinFormsLibrary1
{
public partial class ListBoxUserControl : UserControl
{
private string? _template;
private char? _startSymbol;
private char? _endSymbol;
public int SelectedIndex
{
get
{
return listBox.SelectedIndex;
}
set
{
listBox.SelectedIndex = value;
}
}
public ListBoxUserControl()
{
InitializeComponent();
}
public void SetParams(string template, char? fromChar, char? toChar)
{
_template = template;
_startSymbol = fromChar;
_endSymbol = toChar;
}
public T? GetObject<T>() where T : class, new()
{
if (listBox.SelectedIndex == -1 || string.IsNullOrEmpty(_template) || !_startSymbol.HasValue || !_endSymbol.HasValue)
throw new ArgumentException("Не хватает данных");
var type = typeof(T);
var fields = type.GetFields();
var properties = type.GetProperties();
var members = fields.Cast<MemberInfo>().Concat(properties.Cast<MemberInfo>()).ToArray();
var curObject = new T();
string text = listBox.SelectedItem?.ToString() ?? "";
var words = Regex.Split(_template, $@"\{_startSymbol.Value}.*?\{_endSymbol.Value}");
int firstWordStart = text.IndexOf(words[0], 0);
if (firstWordStart == -1)
throw new Exception("Не найден элемент шаблона");
if (firstWordStart != 0)
{
string beginning = text[..firstWordStart];
FillMember(_template.Substring(1, firstWordStart - 2), curObject, beginning, members);
}
int start = 0;
for (int i = 0; i < words.Length - 1; i++)
{
start = text.IndexOf(words[i], start);
if (start == -1)
throw new Exception("Не найден элемент шаблона");
start += words[i].Length;
int nextWordIndex = text.IndexOf(words[i + 1], start);
if (nextWordIndex == -1)
throw new Exception("Не найден следующий элемент шаблона");
string valueBetween = text[start..nextWordIndex];
string layoutPart = _template.Substring(_template.IndexOf(words[i]) + words[i].Length);
int startCharIndex = layoutPart.IndexOf(_startSymbol.Value);
int endCharIndex = layoutPart.IndexOf(_endSymbol.Value);
string memberName = layoutPart.Substring(startCharIndex + 1, endCharIndex - startCharIndex - 1);
FillMember(memberName, curObject, valueBetween, members);
start = nextWordIndex;
}
return (T?)curObject;
}
private void SetMemberValue(object obj, MemberInfo member, object value)
{
if (member is PropertyInfo property)
{
property.SetValue(obj, value);
}
else if (member is FieldInfo field)
{
field.SetValue(obj, value);
}
}
private void FillMember(string memberName, object curObject, string value, MemberInfo[]? members)
{
var member = members?.FirstOrDefault(x => x.Name == memberName)
?? throw new Exception("Ошибка с поиском элемента");
object convertedValue = Convert.ChangeType(value, GetMemberType(member));
SetMemberValue(curObject, member, convertedValue);
}
private Type GetMemberType(MemberInfo member)
{
return member is PropertyInfo property ? property.PropertyType : ((FieldInfo)member).FieldType;
}
}
}

View 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>

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinFormsLibrary1.Models
{
public class Column
{
public string FieldName { get; set; } = string.Empty;
public string Header { get; set; } = string.Empty;
public int Width { get; set; }
public Column(string fieldName, string header, int width)
{
FieldName = fieldName;
Header = header;
Width = width;
}
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinFormsLibrary1.Models
{
public enum LegendPosition
{
Top,
Right,
Bottom,
Left,
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinFormsLibrary1.Models
{
public class LineChartConfig
{
public string Filepath { get; set; } = string.Empty;
public string Header { get; set; } = string.Empty;
public string ChartTitle { get; set; } = string.Empty;
public Dictionary<string, List<int>> Values { get; set; } = new();
public LegendPosition LegendPosition { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinFormsLibrary1.Models
{
public class MergeCell
{
public string Header;
public int[] CellIndexes;
public MergeCell(string header, int[] cellIndexes)
{
Header = header;
CellIndexes = cellIndexes;
}
}
}

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Excel-DNA.Interop" Version="15.0.1" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,6 @@
namespace WinFormsLibrary2
{
public class Class1
{
}
}

View File

@ -0,0 +1,39 @@
namespace WinFormsLibrary2
{
partial class Form1
{
/// <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.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

View File

@ -0,0 +1,20 @@
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 WinFormsLibrary2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View 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>

View File

@ -0,0 +1,37 @@
namespace WinFormsLibrary2
{
partial class UserControl1
{
/// <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();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
}
#endregion
}
}

View File

@ -0,0 +1,20 @@
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 WinFormsLibrary2
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
}
}

View 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>

View File

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>