Compare commits

..

33 Commits
main ... lab2

Author SHA1 Message Date
6c60e093cc Merge pull request 'lab2_fix' (#4) from lab2_fix into lab2
Reviewed-on: #4
2024-11-28 14:30:07 +04:00
062f92babb Merge pull request 'fix' (#3) from lab2_fix_fix into lab2_fix
Reviewed-on: #3
2024-11-28 14:28:38 +04:00
340c7d9b1f fix 2024-11-28 13:15:44 +04:00
c4d07c4ee2 Merge pull request 'lab2_fix' (#2) from lab2_fix into lab2
Reviewed-on: #2
2024-11-28 00:04:17 +04:00
77b1ea495f Bump version 1.0.3 -> 1.0.4 2024-11-28 00:03:18 +04:00
48fc1a8443 Добавил выброс исключения для CheckedListBox 2024-11-28 00:02:40 +04:00
c853d7790c Создал исключение для CheckedListBox 2024-11-28 00:02:15 +04:00
f128da5093 Merge pull request 'lab2_fix' (#1) from lab2_fix into lab2
Reviewed-on: #1
2024-11-27 23:43:53 +04:00
811e94e0ce Bump version 1.0.2 -> 1.0.3 2024-11-27 23:41:08 +04:00
d5384363ab Правки по checkedlist
Добавил возможность указать максимальное количество чекнутых Item;
При достижении макс. количества последний чекнутый становится не чекнутым;
2024-11-27 23:40:10 +04:00
aefab8a83b Bump version 2024-11-27 20:35:48 +04:00
fe3102ff87 Фикс размеров treeview 2024-11-27 20:34:23 +04:00
ca570ec176 Пофиксил изменение размеров CheckedList 2024-11-27 20:33:06 +04:00
f08da93bb8 Пофиксил изменение размеров DatePicker 2024-11-27 20:27:55 +04:00
ab42ded0da Пофиксил изменение размеров компонента TreeView 2024-11-27 20:26:12 +04:00
250ec241b1 bump version 2024-11-19 23:57:10 +04:00
4039b1b4b9 Add author name 2024-11-19 23:53:50 +04:00
7e50fda55f fix: поправил сборку объекта в TreeView, теперь поля могут быть любого типа 2024-11-19 23:44:02 +04:00
176ba5e313 some change 2024-11-19 20:26:35 +04:00
0c01e4561a Готовая вторая лаба 2024-10-23 17:56:27 +04:00
b78f933bd7 Поменял на savefiledialog 2024-10-07 14:42:26 +04:00
e1d5ffe478 Готов компонент с диаграммой 2024-10-07 14:27:01 +04:00
cbc470fe0f Добавил компонент для круговой диаграммы 2024-10-07 13:20:38 +04:00
976c74f4ac Fix 2024-10-07 13:20:18 +04:00
bc43cb1957 Готов первый компонент с картинкой, переделал на Interop 2024-10-07 12:52:54 +04:00
3c960c8ccb Картинки не вставляются, а так все работает 2024-10-07 00:07:33 +04:00
d46b592899 Добавил логики для сохранения в Excel с прошлого проекта 2024-10-06 21:53:27 +04:00
1efe665054 Создал новый компонент для картинок, пока пустой 2024-10-06 21:52:59 +04:00
8e34e6aca4 Добавил проверки на наличие иерархии 2024-09-23 14:43:10 +04:00
472cd6d16f Завершил разработку treeview 2024-09-23 14:37:08 +04:00
bce34ad0ab завершил разработку второго компонента 2024-09-14 19:00:32 +04:00
d99af1a318 Начал делать второй компонент 2024-09-06 12:58:31 +04:00
26ccde517c Реализовал первый компонент 2024-09-06 12:39:51 +04:00
36 changed files with 2736 additions and 0 deletions

View File

@ -0,0 +1,36 @@
namespace Components
{
partial class ComponentExcelTableWithColumnHeader
{
/// <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,115 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
namespace Components
{
public partial class ComponentExcelTableWithColumnHeader : Component
{
public ComponentExcelTableWithColumnHeader()
{
InitializeComponent();
}
public ComponentExcelTableWithColumnHeader(IContainer container) : this()
{
container.Add(this);
}
public void GenerateExcelFile<T>(
string filePath,
string documentTitle,
List<(int StartRow, int EndRow, int StartCol, int EndCol, string title)> mergeCellsInfo,
List<T> tableData,
List<(string title, string propertyName, float height)> headersConfig)
{
if (string.IsNullOrEmpty(filePath) || headersConfig == null)
{
throw new ArgumentException("Все входные данные должны быть заполнены.");
}
Excel.Application excelApp = new Excel.Application();
excelApp.Visible = false;
Excel.Workbook workbook = excelApp.Workbooks.Add();
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Sheets[1];
worksheet.Cells[1, 1].Value = documentTitle;
worksheet.Range[worksheet.Cells[1, 1], worksheet.Cells[1, tableData.Count + 2]].Merge();
worksheet.Cells[1, 1].HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
for (int i = 0; i < headersConfig.Count; i++)
{
worksheet.Cells[2 + i, 2].Value = headersConfig[i].title;
worksheet.Cells[2 + i, 2].Font.Bold = true;
worksheet.Rows[i + 1].RowHeight = headersConfig[i].height;
}
for (int colIndex = 0; colIndex < tableData.Count; colIndex++)
{
var data = tableData[colIndex];
for (int rowIndex = 0; rowIndex < headersConfig.Count; rowIndex++)
{
var property = data.GetType().GetProperty(headersConfig[rowIndex].propertyName);
if (property != null)
{
worksheet.Cells[rowIndex + 2, colIndex + 3].Value = property.GetValue(data);
}
}
}
List<int> rows = new List<int>();
foreach (var mergeInfo in mergeCellsInfo)
{
ValidateMergeCells(mergeCellsInfo);
worksheet.Range[worksheet.Cells[mergeInfo.StartRow + 1, mergeInfo.StartCol],
worksheet.Cells[mergeInfo.EndRow + 1, mergeInfo.EndCol]].Merge();
worksheet.Cells[mergeInfo.StartRow + 1, mergeInfo.StartCol].Value = mergeInfo.title;
for (int r = mergeInfo.StartRow + 1; r <= mergeInfo.EndRow + 1; r++)
{
rows.Add(r);
}
}
for (int i = 2; i < headersConfig.Count + 2; i++)
{
if (!rows.Contains(i))
{
worksheet.Range[worksheet.Cells[i, 1], worksheet.Cells[i, 2]].Merge();
}
}
workbook.SaveAs(filePath);
workbook.Close();
Marshal.ReleaseComObject(workbook);
excelApp.Quit();
Marshal.ReleaseComObject(excelApp);
}
private void ValidateMergeCells(List<(int StartRow, int EndRow, int StartCol, int EndCol, string title)> mergeCellsInfo)
{
for (int i = 0; i < mergeCellsInfo.Count; i++)
{
for (int j = i + 1; j < mergeCellsInfo.Count; j++)
{
if (CellsOverlap(mergeCellsInfo[i], mergeCellsInfo[j]))
{
throw new InvalidOperationException("Объединенные ячейки пересекаются.");
}
}
}
}
private bool CellsOverlap(
(int StartRow, int EndRow, int StartCol, int EndCol, string title) range1,
(int StartRow, int EndRow, int StartCol, int EndCol, string title) range2)
{
bool rowsOverlap = range1.StartRow <= range2.EndRow && range1.EndRow >= range2.StartRow;
bool colsOverlap = range1.StartCol <= range2.EndCol && range1.EndCol >= range2.StartCol;
return rowsOverlap && colsOverlap;
}
}
}

View File

@ -0,0 +1,36 @@
namespace Components
{
partial class ComponentExcelWithImage
{
/// <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,108 @@
using Excel = Microsoft.Office.Interop.Excel;
using System.ComponentModel;
namespace Components
{
public partial class ComponentExcelWithImage : Component
{
public ComponentExcelWithImage()
{
InitializeComponent();
}
public ComponentExcelWithImage(IContainer container) : this()
{
container.Add(this);
}
private void CheckInputValues(string filePath, string tableTitle, string[] imagePaths)
{
if (string.IsNullOrEmpty(filePath))
{
throw new ArgumentNullException(nameof(filePath));
}
if (string.IsNullOrEmpty(tableTitle))
{
throw new ArgumentNullException(nameof(tableTitle));
}
if (imagePaths == null)
{
throw new ArgumentNullException(nameof(imagePaths));
}
foreach (string imagePath in imagePaths)
{
if (string.IsNullOrEmpty(imagePath))
{
throw new ArgumentNullException("Image path is null");
}
}
}
public void CreateExcelWithImages(string filePath, string tableTitle, string[] imagePaths)
{
CheckInputValues(filePath, tableTitle, imagePaths);
Excel.Application excelApp = new Excel.Application();
Excel.Workbook workbook = excelApp.Workbooks.Add();
Excel.Worksheet worksheet = workbook.Sheets[1];
worksheet.Cells[1, 1] = tableTitle;
InsertImagesInSingleCell(worksheet, imagePaths, 2, 1);
workbook.SaveAs(filePath);
workbook.Close();
excelApp.Quit();
ReleaseObject(worksheet);
ReleaseObject(workbook);
ReleaseObject(excelApp);
}
private void InsertImagesInSingleCell(Excel.Worksheet worksheet, string[] imagePaths, int rowIndex, int columnIndex)
{
Excel.Range cell = worksheet.Cells[rowIndex, columnIndex];
double currentTopOffset = 0;
foreach (string imagePath in imagePaths)
{
if (File.Exists(imagePath))
{
Excel.Pictures pictures = (Excel.Pictures)worksheet.Pictures(System.Reflection.Missing.Value);
Excel.Picture picture = pictures.Insert(imagePath);
picture.Left = cell.Left;
picture.Top = cell.Top + currentTopOffset;
currentTopOffset += picture.Height;
}
else
{
throw new FileNotFoundException("Image not found at: " + imagePath);
}
}
}
private void ReleaseObject(object obj)
{
try
{
if (obj != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
}
catch (Exception ex)
{
obj = null;
Console.WriteLine("Error releasing object: " + ex.ToString());
}
finally
{
GC.Collect();
}
}
}
}

View File

@ -0,0 +1,36 @@
namespace Components
{
partial class ComponentExcelWithPieDiagram
{
/// <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,159 @@
using System.ComponentModel;
using Excel = Microsoft.Office.Interop.Excel;
namespace Components
{
public partial class ComponentExcelWithPieDiagram : Component
{
public ComponentExcelWithPieDiagram()
{
InitializeComponent();
}
public ComponentExcelWithPieDiagram(IContainer container) : this()
{
container.Add(this);
}
public enum LegendPosition
{
Top,
Bottom,
Left,
Right
}
public class ChartData
{
[DisplayName("Серия")]
public string SeriesName { get; set; }
[DisplayName("Значение")]
public double SeriesValue { get; set; }
}
private void CheckInputValues(
string filePath,
string fileTitle,
string chartTitle,
LegendPosition legendPosition,
List<ChartData> data)
{
if (string.IsNullOrEmpty(filePath))
{
throw new ArgumentNullException(nameof(filePath));
}
if (string.IsNullOrEmpty(fileTitle))
{
throw new ArgumentNullException(nameof(fileTitle));
}
if (string.IsNullOrEmpty(chartTitle))
{
throw new ArgumentNullException(nameof(chartTitle));
}
double chartSum = 0;
foreach (var item in data)
{
if (!string.IsNullOrEmpty(item.SeriesName)) { chartSum += item.SeriesValue; }
else
{
throw new ArgumentNullException("Series name is null or empty");
}
if (item.SeriesValue == 0 || item.SeriesValue > 100)
{
throw new ArgumentOutOfRangeException("Series value is out of range");
}
}
if (chartSum > 100)
{
throw new ArgumentOutOfRangeException("Series values sum is out of range");
}
}
public void CreateExcelWithPieChart(
string filePath,
string fileTitle,
string chartTitle,
LegendPosition legendPosition,
List<ChartData> data)
{
CheckInputValues(filePath, fileTitle, chartTitle, legendPosition, data);
Excel.Application excelApp = new Excel.Application();
Excel.Workbook workbook = excelApp.Workbooks.Add();
Excel.Worksheet worksheet = workbook.Sheets[1];
worksheet.Cells[1, 1] = fileTitle;
int dataStartRow = 3;
for (int i = 0; i < data.Count; i++)
{
worksheet.Cells[dataStartRow + i, 1] = data[i].SeriesName;
worksheet.Cells[dataStartRow + i, 2] = data[i].SeriesValue;
}
Excel.ChartObjects chartObjects = (Excel.ChartObjects)worksheet.ChartObjects();
Excel.ChartObject chartObject = chartObjects.Add(300, 50, 400, 300);
Excel.Chart chart = chartObject.Chart;
chart.ChartType = Excel.XlChartType.xlPie;
Excel.Range chartRange = worksheet.get_Range("A3", $"B{dataStartRow + data.Count - 1}");
chart.SetSourceData(chartRange);
chart.HasTitle = true;
chart.ChartTitle.Text = chartTitle;
SetLegendPosition(chart, legendPosition);
workbook.SaveAs(filePath);
workbook.Close();
excelApp.Quit();
ReleaseObject(worksheet);
ReleaseObject(workbook);
ReleaseObject(excelApp);
}
private void SetLegendPosition(Excel.Chart chart, LegendPosition legendPosition)
{
chart.HasLegend = true;
switch (legendPosition)
{
case LegendPosition.Top:
chart.Legend.Position = Excel.XlLegendPosition.xlLegendPositionTop;
break;
case LegendPosition.Bottom:
chart.Legend.Position = Excel.XlLegendPosition.xlLegendPositionBottom;
break;
case LegendPosition.Left:
chart.Legend.Position = Excel.XlLegendPosition.xlLegendPositionLeft;
break;
case LegendPosition.Right:
chart.Legend.Position = Excel.XlLegendPosition.xlLegendPositionRight;
break;
}
}
private void ReleaseObject(object obj)
{
try
{
if (obj != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
}
catch (Exception ex)
{
obj = null;
Console.WriteLine("Error releasing object: " + ex.ToString());
}
finally
{
GC.Collect();
}
}
}
}

View File

@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Authors>ns.potapov</Authors>
<VersionPrefix>1.0.5</VersionPrefix>
<Version>$(VersionPrefix)</Version>
</PropertyGroup>
<ItemGroup>
<COMReference Include="Microsoft.Office.Interop.Excel">
<WrapperTool>tlbimp</WrapperTool>
<VersionMinor>9</VersionMinor>
<VersionMajor>1</VersionMajor>
<Guid>00020813-0000-0000-c000-000000000046</Guid>
<Lcid>0</Lcid>
<Isolated>false</Isolated>
<EmbedInteropTypes>true</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="3.1.0" />
<PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,13 @@
namespace Components.Exceptions
{
internal class MaxCheckedItemsCountExceedException : Exception
{
public MaxCheckedItemsCountExceedException()
{
}
public MaxCheckedItemsCountExceedException(string? message) : base(message)
{
}
}
}

View File

@ -0,0 +1,7 @@
namespace Components.Exceptions
{
public class NodeIsNotLeafException : UserControlTreeViewException
{
public NodeIsNotLeafException() : base("Selected node is not a leaf") { }
}
}

View File

@ -0,0 +1,7 @@
namespace Components.Exceptions
{
public class NotSelectedNodeException : UserControlTreeViewException
{
public NotSelectedNodeException() : base("Node is not selected") { }
}
}

View File

@ -0,0 +1,7 @@
namespace Components.Exceptions
{
public class PropertyNotDeclaratedException : UserControlTreeViewException
{
public PropertyNotDeclaratedException(string propName) : base($"Property \"{propName}\" not declared") { }
}
}

View File

@ -0,0 +1,7 @@
namespace Components.Exceptions
{
public class PropertyNullException : UserControlTreeViewException
{
public PropertyNullException(string propName) : base($"Property \"{propName}\" is null") { }
}
}

View File

@ -0,0 +1,8 @@
namespace Components.Exceptions
{
public class RangeNotSetException : Exception
{
public RangeNotSetException() { }
public RangeNotSetException(string message) : base(message) { }
}
}

View File

@ -0,0 +1,7 @@
namespace Components.Exceptions
{
public class TreeHierarchyNotSetException : UserControlTreeViewException
{
public TreeHierarchyNotSetException() : base("Tree hierarchy not set") { }
}
}

View File

@ -0,0 +1,8 @@
namespace Components.Exceptions
{
public class UserControlTreeViewException : Exception
{
public UserControlTreeViewException() { }
public UserControlTreeViewException(string message) : base(message) { }
}
}

View File

@ -0,0 +1,8 @@
namespace Components.Exceptions
{
public class ValueOutOfRangeException : Exception
{
public ValueOutOfRangeException() { }
public ValueOutOfRangeException(string message) : base(message) { }
}
}

View File

@ -0,0 +1,62 @@
namespace Components
{
partial class UserControlCheckedList
{
/// <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.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
checkedListBox.CheckOnClick = true;
checkedListBox.FormattingEnabled = true;
checkedListBox.Location = new Point(9, 8);
checkedListBox.Margin = new Padding(3, 4, 3, 4);
checkedListBox.Name = "checkedListBox";
checkedListBox.Size = new Size(509, 400);
checkedListBox.TabIndex = 0;
checkedListBox.ItemCheck += checkedListBox_ItemCheck;
//
// UserControlCheckedList
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.Firebrick;
Controls.Add(checkedListBox);
Margin = new Padding(3, 4, 3, 4);
Name = "UserControlCheckedList";
Size = new Size(527, 415);
ResumeLayout(false);
}
#endregion
private CheckedListBox checkedListBox;
}
}

View File

@ -0,0 +1,100 @@
using Components.Exceptions;
namespace Components
{
public enum Types : int
{
Exception = 0,
DeleteFirst = 1,
}
public partial class UserControlCheckedList : UserControl
{
public int MaxCheckedItemsCount { get; set; } = 1;
private Types typeOfMaxChecked = Types.DeleteFirst;
private EventHandler _onCheckedItemChangedEvent;
public void ChangeTypeOfMaxChecked(Types type)
{
typeOfMaxChecked = type;
}
public event EventHandler CheckedItemChanged
{
add
{
_onCheckedItemChangedEvent += value;
}
remove
{
_onCheckedItemChangedEvent -= value;
}
}
public string CheckedItem
{
get
{
return checkedListBox.CheckedItems[0] as string ?? string.Empty;
}
set
{
if (checkedListBox.Items.Contains(value))
{
checkedListBox.SetItemCheckState(checkedListBox.Items.IndexOf(value), CheckState.Checked);
}
}
}
public List<string> CheckedItems
{
get
{
List<string> list = new List<string>();
foreach(var item in checkedListBox.CheckedItems )
{
list.Add(item.ToString());
}
return list;
}
set
{
if (checkedListBox.Items.Contains(value))
{
checkedListBox.SetItemCheckState(checkedListBox.Items.IndexOf(value), CheckState.Checked);
}
}
}
public UserControlCheckedList()
{
InitializeComponent();
}
public void SetCheckedListBoxValues(List<string> values)
{
ClearCheckedListBoxValues();
foreach (var item in values)
{
checkedListBox.Items.Add(item);
}
}
public void ClearCheckedListBoxValues()
{
checkedListBox.Items.Clear();
}
private void checkedListBox_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (checkedListBox.CheckedItems.Count > MaxCheckedItemsCount)
{
if (typeOfMaxChecked == Types.Exception)
{
checkedListBox.SetItemChecked(e.Index, false);
throw new MaxCheckedItemsCountExceedException("Превышено максимальное число выбранных элементов");
}
else if (typeOfMaxChecked == Types.DeleteFirst)
{
checkedListBox.SetItemChecked(0, false);
}
}
_onCheckedItemChangedEvent?.Invoke(sender, 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,61 @@
namespace Components
{
partial class UserControlDatePicker
{
/// <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()
{
dateTimePicker = new DateTimePicker();
SuspendLayout();
//
// dateTimePicker
//
dateTimePicker.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
dateTimePicker.Format = DateTimePickerFormat.Short;
dateTimePicker.Location = new Point(3, 4);
dateTimePicker.Margin = new Padding(3, 4, 3, 4);
dateTimePicker.Name = "dateTimePicker";
dateTimePicker.Size = new Size(120, 27);
dateTimePicker.TabIndex = 0;
dateTimePicker.ValueChanged += dateTimePicker_ValueChanged;
//
// UserControlDatePicker
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.Orange;
Controls.Add(dateTimePicker);
Margin = new Padding(3, 4, 3, 4);
Name = "UserControlDatePicker";
Size = new Size(126, 36);
ResumeLayout(false);
}
#endregion
private DateTimePicker dateTimePicker;
}
}

View File

@ -0,0 +1,55 @@
using Components.Exceptions;
namespace Components
{
public partial class UserControlDatePicker : UserControl
{
public DateTime? MinDate;
public DateTime? MaxDate;
public DateTime Date
{
get
{
if (MinDate == null || MaxDate == null)
{
throw new RangeNotSetException("Диапазон дат не задан");
}
if (dateTimePicker.Value < MinDate || dateTimePicker.Value > MaxDate)
{
throw new ValueOutOfRangeException("Значение даты вне диапазона");
}
return dateTimePicker.Value;
}
set
{
if (MinDate != null && MaxDate != null)
{
if (value >= MinDate && value <= MaxDate)
{
dateTimePicker.Value = value;
}
}
}
}
private EventHandler _onValueChangedEvent;
public event EventHandler ValueChanged
{
add
{
_onValueChangedEvent += value;
}
remove
{
_onValueChangedEvent -= value;
}
}
public UserControlDatePicker()
{
InitializeComponent();
}
private void dateTimePicker_ValueChanged(object sender, EventArgs e)
{
_onValueChangedEvent?.Invoke(sender, 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,59 @@
namespace Components
{
partial class UserControlTreeView
{
/// <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.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
treeView.Location = new Point(11, 10);
treeView.Margin = new Padding(3, 4, 3, 4);
treeView.Name = "treeView";
treeView.Size = new Size(636, 494);
treeView.TabIndex = 0;
//
// UserControlTreeView
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = SystemColors.ActiveCaption;
Controls.Add(treeView);
Margin = new Padding(3, 4, 3, 4);
Name = "UserControlTreeView";
Size = new Size(658, 514);
ResumeLayout(false);
}
#endregion
private TreeView treeView;
}
}

View File

@ -0,0 +1,143 @@
using Components.Exceptions;
using System.Reflection;
namespace Components
{
public partial class UserControlTreeView : UserControl
{
public int SelectedIndex
{
get
{
return treeView.SelectedNode?.Index ?? -1;
}
set
{
if (value > -1 && value < treeView.Nodes.Count)
{
treeView.SelectedNode = treeView.Nodes[value];
}
}
}
private List<(string PropertyName, bool AlwaysCreateBranch)> Hierarchy;
public UserControlTreeView()
{
InitializeComponent();
Hierarchy = [];
}
public T GetObjectSelectedNode<T>()
where T : class, new()
{
var node = treeView.SelectedNode;
if (node == null)
{
throw new NotSelectedNodeException();
}
if ((Hierarchy?.Count ?? 0) == 0)
{
throw new TreeHierarchyNotSetException();
}
if (node.Nodes.Count > 0)
{
throw new NodeIsNotLeafException();
}
T obj = new T();
int propIndex = GetNodeDepth(node);
while (node != null)
{
object propValue = node.Tag;
string propName = Hierarchy[propIndex].PropertyName;
var prop = obj.GetType().GetProperty(propName);
if (prop == null)
{
throw new PropertyNotDeclaratedException(propName);
}
prop.SetValue(obj, propValue);
node = node.Parent;
propIndex--;
}
return obj;
}
private int GetNodeDepth(TreeNode node)
{
int depth = 0;
while (node.Parent != null)
{
depth++;
node = node.Parent;
}
return depth;
}
public void SetTreeObjects<T>(List<T> objects)
{
if (objects.Count == 0)
{
return;
}
if ((Hierarchy?.Count ?? 0) == 0)
{
throw new TreeHierarchyNotSetException();
}
PropertyInfo[]? properties = objects[0]!.GetType().GetProperties();
ClearTreeView();
foreach (T obj in objects)
{
var nodes = treeView.Nodes;
foreach (var hierarchyProperty in Hierarchy)
{
PropertyInfo? objectPropertyInfo = properties?.Single(prop => prop.Name == hierarchyProperty.PropertyName);
if (objectPropertyInfo == null)
{
throw new PropertyNotDeclaratedException(hierarchyProperty.PropertyName);
}
object? objectPropertyValue = objectPropertyInfo.GetValue(obj);
if (objectPropertyValue == null)
{
throw new PropertyNullException(hierarchyProperty.PropertyName);
}
TreeNode? node = null;
if (!hierarchyProperty.AlwaysCreateBranch)
{
foreach (TreeNode childNode in nodes)
{
if (childNode.Text == objectPropertyValue.ToString())
{
node = childNode;
break;
}
}
}
if (node == null)
{
node = nodes.Add(objectPropertyValue.ToString());
node.Tag = objectPropertyValue;
}
nodes = node.Nodes;
}
}
}
public void SetHierarchy(List<(string PropertyName, bool AlwaysCreateBranch)> hierarchy)
{
Hierarchy = hierarchy;
}
public void ClearTreeView()
{
treeView.Nodes.Clear();
treeView.Update();
}
}
}

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,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35222.181
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Components", "Components\Components.csproj", "{18A921F6-FEBD-44BE-B74B-693AD384FD65}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinFormsApp", "WinFormsApp\WinFormsApp.csproj", "{B2B2491A-9FAF-4682-B859-CEA0D63E593E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{18A921F6-FEBD-44BE-B74B-693AD384FD65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{18A921F6-FEBD-44BE-B74B-693AD384FD65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18A921F6-FEBD-44BE-B74B-693AD384FD65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18A921F6-FEBD-44BE-B74B-693AD384FD65}.Release|Any CPU.Build.0 = Release|Any CPU
{B2B2491A-9FAF-4682-B859-CEA0D63E593E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B2B2491A-9FAF-4682-B859-CEA0D63E593E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B2B2491A-9FAF-4682-B859-CEA0D63E593E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B2B2491A-9FAF-4682-B859-CEA0D63E593E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {431FB736-164C-4849-B179-D048D3651094}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,24 @@
namespace WinFormsApp
{
public class Employee
{
public int Id { get; set; }
public string Departament { get; set; }
public string Position { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public Employee() { }
public Employee(string departament, string position, string surname, string name)
{
Id = new Random().Next(4);
Departament = departament;
Position = position;
Name = name;
Surname = surname;
}
public override string ToString()
{
return Id.ToString() + ", " + Departament + ", " + Position + ", " + Surname + " " + Name;
}
}
}

View File

@ -0,0 +1,393 @@
namespace WinFormsApp
{
partial class FormNoVisual
{
/// <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()
{
components = new System.ComponentModel.Container();
componentExcelWithImage = new Components.ComponentExcelWithImage(components);
textBoxFilePath = new TextBox();
buttonSetFilePath = new Button();
textBoxTitle = new TextBox();
listBoxImages = new ListBox();
buttonCreateExcelFile = new Button();
buttonAddImage = new Button();
buttonClearImages = new Button();
componentExcelWithPieDiagram = new Components.ComponentExcelWithPieDiagram(components);
dataGridViewSeries = new DataGridView();
textBoxSeriesName = new TextBox();
numericUpDownSeriesValue = new NumericUpDown();
buttonAddSeries = new Button();
buttonClearSeries = new Button();
buttonCreateExcelWithPieDiagram = new Button();
comboBoxLegendPosition = new ComboBox();
labelLegendPosition = new Label();
textBoxDiagramTitle = new TextBox();
componentExcelTableWithColumnHeader = new Components.ComponentExcelTableWithColumnHeader(components);
dataGridViewEmployees = new DataGridView();
textBoxSurname = new TextBox();
textBoxName = new TextBox();
numericUpDownAge = new NumericUpDown();
label1 = new Label();
textBoxWorkPlace = new TextBox();
textBoxPost = new TextBox();
textBoxSalary = new TextBox();
buttonAddEmployee = new Button();
buttonClearEmployes = new Button();
buttonGenerateExcelWithTable = new Button();
((System.ComponentModel.ISupportInitialize)dataGridViewSeries).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDownSeriesValue).BeginInit();
((System.ComponentModel.ISupportInitialize)dataGridViewEmployees).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDownAge).BeginInit();
SuspendLayout();
//
// textBoxFilePath
//
textBoxFilePath.Location = new Point(12, 12);
textBoxFilePath.Name = "textBoxFilePath";
textBoxFilePath.PlaceholderText = "Путь к файлу";
textBoxFilePath.ReadOnly = true;
textBoxFilePath.Size = new Size(248, 27);
textBoxFilePath.TabIndex = 0;
//
// buttonSetFilePath
//
buttonSetFilePath.Location = new Point(275, 10);
buttonSetFilePath.Name = "buttonSetFilePath";
buttonSetFilePath.Size = new Size(94, 29);
buttonSetFilePath.TabIndex = 1;
buttonSetFilePath.Text = "Выбрать";
buttonSetFilePath.UseVisualStyleBackColor = true;
buttonSetFilePath.Click += buttonSetFilePath_Click;
//
// textBoxTitle
//
textBoxTitle.Location = new Point(12, 45);
textBoxTitle.Name = "textBoxTitle";
textBoxTitle.PlaceholderText = "Заголовок";
textBoxTitle.Size = new Size(357, 27);
textBoxTitle.TabIndex = 2;
//
// listBoxImages
//
listBoxImages.FormattingEnabled = true;
listBoxImages.Location = new Point(12, 127);
listBoxImages.Name = "listBoxImages";
listBoxImages.Size = new Size(357, 104);
listBoxImages.TabIndex = 3;
//
// buttonCreateExcelFile
//
buttonCreateExcelFile.Location = new Point(12, 272);
buttonCreateExcelFile.Name = "buttonCreateExcelFile";
buttonCreateExcelFile.Size = new Size(357, 29);
buttonCreateExcelFile.TabIndex = 4;
buttonCreateExcelFile.Text = "Создать Excel файл с картинкой";
buttonCreateExcelFile.UseVisualStyleBackColor = true;
buttonCreateExcelFile.Click += buttonCreateExcelFile_Click;
//
// buttonAddImage
//
buttonAddImage.Location = new Point(12, 237);
buttonAddImage.Name = "buttonAddImage";
buttonAddImage.Size = new Size(257, 29);
buttonAddImage.TabIndex = 5;
buttonAddImage.Text = "Добавить изображение";
buttonAddImage.UseVisualStyleBackColor = true;
buttonAddImage.Click += buttonAddImage_Click;
//
// buttonClearImages
//
buttonClearImages.Location = new Point(275, 237);
buttonClearImages.Name = "buttonClearImages";
buttonClearImages.Size = new Size(94, 29);
buttonClearImages.TabIndex = 6;
buttonClearImages.Text = "Очистить";
buttonClearImages.UseVisualStyleBackColor = true;
buttonClearImages.Click += buttonClearImages_Click;
//
// dataGridViewSeries
//
dataGridViewSeries.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewSeries.Enabled = false;
dataGridViewSeries.Location = new Point(406, 10);
dataGridViewSeries.MultiSelect = false;
dataGridViewSeries.Name = "dataGridViewSeries";
dataGridViewSeries.ReadOnly = true;
dataGridViewSeries.RowHeadersVisible = false;
dataGridViewSeries.RowHeadersWidth = 51;
dataGridViewSeries.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewSeries.Size = new Size(300, 115);
dataGridViewSeries.TabIndex = 7;
//
// textBoxSeriesName
//
textBoxSeriesName.Location = new Point(406, 166);
textBoxSeriesName.Name = "textBoxSeriesName";
textBoxSeriesName.PlaceholderText = "Название серии";
textBoxSeriesName.Size = new Size(200, 27);
textBoxSeriesName.TabIndex = 8;
//
// numericUpDownSeriesValue
//
numericUpDownSeriesValue.DecimalPlaces = 2;
numericUpDownSeriesValue.Increment = new decimal(new int[] { 1, 0, 0, 65536 });
numericUpDownSeriesValue.Location = new Point(406, 199);
numericUpDownSeriesValue.Name = "numericUpDownSeriesValue";
numericUpDownSeriesValue.Size = new Size(125, 27);
numericUpDownSeriesValue.TabIndex = 9;
numericUpDownSeriesValue.TextAlign = HorizontalAlignment.Right;
//
// buttonAddSeries
//
buttonAddSeries.Location = new Point(612, 166);
buttonAddSeries.Name = "buttonAddSeries";
buttonAddSeries.Size = new Size(94, 29);
buttonAddSeries.TabIndex = 10;
buttonAddSeries.Text = "Добавить";
buttonAddSeries.UseVisualStyleBackColor = true;
buttonAddSeries.Click += buttonAddSeries_Click;
//
// buttonClearSeries
//
buttonClearSeries.Location = new Point(537, 199);
buttonClearSeries.Name = "buttonClearSeries";
buttonClearSeries.Size = new Size(169, 29);
buttonClearSeries.TabIndex = 11;
buttonClearSeries.Text = "Очистить данные";
buttonClearSeries.UseVisualStyleBackColor = true;
buttonClearSeries.Click += buttonClearSeries_Click;
//
// buttonCreateExcelWithPieDiagram
//
buttonCreateExcelWithPieDiagram.Location = new Point(406, 272);
buttonCreateExcelWithPieDiagram.Name = "buttonCreateExcelWithPieDiagram";
buttonCreateExcelWithPieDiagram.Size = new Size(300, 29);
buttonCreateExcelWithPieDiagram.TabIndex = 12;
buttonCreateExcelWithPieDiagram.Text = "Создать Excel файл с диаграммой";
buttonCreateExcelWithPieDiagram.UseVisualStyleBackColor = true;
buttonCreateExcelWithPieDiagram.Click += buttonCreateExcelWithPieDiagram_Click;
//
// comboBoxLegendPosition
//
comboBoxLegendPosition.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxLegendPosition.FormattingEnabled = true;
comboBoxLegendPosition.Location = new Point(581, 234);
comboBoxLegendPosition.Name = "comboBoxLegendPosition";
comboBoxLegendPosition.Size = new Size(125, 28);
comboBoxLegendPosition.TabIndex = 13;
//
// labelLegendPosition
//
labelLegendPosition.AutoSize = true;
labelLegendPosition.Location = new Point(406, 237);
labelLegendPosition.Name = "labelLegendPosition";
labelLegendPosition.Size = new Size(177, 20);
labelLegendPosition.TabIndex = 14;
labelLegendPosition.Text = "Расположение легенды:";
//
// textBoxDiagramTitle
//
textBoxDiagramTitle.Location = new Point(406, 131);
textBoxDiagramTitle.Name = "textBoxDiagramTitle";
textBoxDiagramTitle.PlaceholderText = "Заголовок диаграммы";
textBoxDiagramTitle.Size = new Size(300, 27);
textBoxDiagramTitle.TabIndex = 15;
//
// dataGridViewEmployees
//
dataGridViewEmployees.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
dataGridViewEmployees.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewEmployees.Location = new Point(779, 12);
dataGridViewEmployees.Name = "dataGridViewEmployees";
dataGridViewEmployees.RowHeadersVisible = false;
dataGridViewEmployees.RowHeadersWidth = 51;
dataGridViewEmployees.Size = new Size(619, 201);
dataGridViewEmployees.TabIndex = 16;
//
// textBoxSurname
//
textBoxSurname.Location = new Point(782, 219);
textBoxSurname.Name = "textBoxSurname";
textBoxSurname.PlaceholderText = "Фамилия";
textBoxSurname.Size = new Size(164, 27);
textBoxSurname.TabIndex = 17;
//
// textBoxName
//
textBoxName.Location = new Point(782, 256);
textBoxName.Name = "textBoxName";
textBoxName.PlaceholderText = "Имя";
textBoxName.Size = new Size(164, 27);
textBoxName.TabIndex = 18;
//
// numericUpDownAge
//
numericUpDownAge.Location = new Point(858, 292);
numericUpDownAge.Name = "numericUpDownAge";
numericUpDownAge.Size = new Size(88, 27);
numericUpDownAge.TabIndex = 19;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(782, 294);
label1.Name = "label1";
label1.Size = new Size(64, 20);
label1.TabIndex = 20;
label1.Text = "Возраст";
//
// textBoxWorkPlace
//
textBoxWorkPlace.Location = new Point(980, 219);
textBoxWorkPlace.Name = "textBoxWorkPlace";
textBoxWorkPlace.PlaceholderText = "Место работы";
textBoxWorkPlace.Size = new Size(164, 27);
textBoxWorkPlace.TabIndex = 21;
//
// textBoxPost
//
textBoxPost.Location = new Point(980, 256);
textBoxPost.Name = "textBoxPost";
textBoxPost.PlaceholderText = "Должность";
textBoxPost.Size = new Size(164, 27);
textBoxPost.TabIndex = 22;
//
// textBoxSalary
//
textBoxSalary.Location = new Point(980, 292);
textBoxSalary.Name = "textBoxSalary";
textBoxSalary.PlaceholderText = "Зарплата";
textBoxSalary.Size = new Size(164, 27);
textBoxSalary.TabIndex = 23;
//
// buttonAddEmployee
//
buttonAddEmployee.Location = new Point(1150, 219);
buttonAddEmployee.Name = "buttonAddEmployee";
buttonAddEmployee.Size = new Size(94, 29);
buttonAddEmployee.TabIndex = 24;
buttonAddEmployee.Text = "Добавить";
buttonAddEmployee.UseVisualStyleBackColor = true;
buttonAddEmployee.Click += buttonAddEmployee_Click;
//
// buttonClearEmployes
//
buttonClearEmployes.Location = new Point(1250, 219);
buttonClearEmployes.Name = "buttonClearEmployes";
buttonClearEmployes.Size = new Size(94, 29);
buttonClearEmployes.TabIndex = 25;
buttonClearEmployes.Text = "Очистить";
buttonClearEmployes.UseVisualStyleBackColor = true;
buttonClearEmployes.Click += buttonClearEmployes_Click;
//
// buttonGenerateExcelWithTable
//
buttonGenerateExcelWithTable.Location = new Point(1149, 256);
buttonGenerateExcelWithTable.Name = "buttonGenerateExcelWithTable";
buttonGenerateExcelWithTable.Size = new Size(195, 29);
buttonGenerateExcelWithTable.TabIndex = 26;
buttonGenerateExcelWithTable.Text = "Сгенерировать";
buttonGenerateExcelWithTable.UseVisualStyleBackColor = true;
buttonGenerateExcelWithTable.Click += buttonGenerateExcelWithTable_Click;
//
// FormNoVisual
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1410, 446);
Controls.Add(buttonGenerateExcelWithTable);
Controls.Add(buttonClearEmployes);
Controls.Add(buttonAddEmployee);
Controls.Add(textBoxSalary);
Controls.Add(textBoxPost);
Controls.Add(textBoxWorkPlace);
Controls.Add(label1);
Controls.Add(numericUpDownAge);
Controls.Add(textBoxName);
Controls.Add(textBoxSurname);
Controls.Add(dataGridViewEmployees);
Controls.Add(textBoxDiagramTitle);
Controls.Add(labelLegendPosition);
Controls.Add(comboBoxLegendPosition);
Controls.Add(buttonCreateExcelWithPieDiagram);
Controls.Add(buttonClearSeries);
Controls.Add(buttonAddSeries);
Controls.Add(numericUpDownSeriesValue);
Controls.Add(textBoxSeriesName);
Controls.Add(dataGridViewSeries);
Controls.Add(buttonClearImages);
Controls.Add(buttonAddImage);
Controls.Add(buttonCreateExcelFile);
Controls.Add(listBoxImages);
Controls.Add(textBoxTitle);
Controls.Add(buttonSetFilePath);
Controls.Add(textBoxFilePath);
Name = "FormNoVisual";
Text = "FormNoVisual";
((System.ComponentModel.ISupportInitialize)dataGridViewSeries).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDownSeriesValue).EndInit();
((System.ComponentModel.ISupportInitialize)dataGridViewEmployees).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDownAge).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Components.ComponentExcelWithImage componentExcelWithImage;
private TextBox textBoxFilePath;
private Button buttonSetFilePath;
private TextBox textBoxTitle;
private ListBox listBoxImages;
private Button buttonCreateExcelFile;
private Button buttonAddImage;
private Button buttonClearImages;
private Components.ComponentExcelWithPieDiagram componentExcelWithPieDiagram;
private DataGridView dataGridViewSeries;
private TextBox textBoxSeriesName;
private NumericUpDown numericUpDownSeriesValue;
private Button buttonAddSeries;
private Button buttonClearSeries;
private Button buttonCreateExcelWithPieDiagram;
private ComboBox comboBoxLegendPosition;
private Label labelLegendPosition;
private TextBox textBoxDiagramTitle;
private Components.ComponentExcelTableWithColumnHeader componentExcelTableWithColumnHeader;
private DataGridView dataGridViewEmployees;
private TextBox textBoxSurname;
private TextBox textBoxName;
private NumericUpDown numericUpDownAge;
private Label label1;
private TextBox textBoxWorkPlace;
private TextBox textBoxPost;
private TextBox textBoxSalary;
private Button buttonAddEmployee;
private Button buttonClearEmployes;
private Button buttonGenerateExcelWithTable;
}
}

View File

@ -0,0 +1,224 @@
using Components;
using System.Collections.Generic;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using LegendPosition = Components.ComponentExcelWithPieDiagram.LegendPosition;
namespace WinFormsApp
{
public partial class FormNoVisual : Form
{
private List<ComponentExcelWithPieDiagram.ChartData> _chartData;
private class TestData
{
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
}
private List<TableEmployee> _employees = new List<TableEmployee>();
private double _chartDataValuesSum
{
get
{
return _chartData.Sum(x => x.SeriesValue);
}
}
public FormNoVisual()
{
InitializeComponent();
_chartData = new List<ComponentExcelWithPieDiagram.ChartData>();
comboBoxLegendPosition.DataSource = Enum.GetValues(typeof(LegendPosition));
UpdateNumericUpDownSeriesValueMaximumValue();
}
private void buttonCreateExcelFile_Click(object sender, EventArgs e)
{
string[] list = new string[listBoxImages.Items.Count];
for (int i = 0; i < listBoxImages.Items.Count; i++)
{
list[i] = listBoxImages.Items[i].ToString();
}
try
{
componentExcelWithImage.CreateExcelWithImages(textBoxFilePath.Text, textBoxTitle.Text, list);
MessageBox.Show("Файл успешно создан", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"Ошибка при создании файла:\n{ex.Message}", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonSetFilePath_Click(object sender, EventArgs e)
{
var filePath = string.Empty;
using (SaveFileDialog saveFileDialog = new SaveFileDialog())
{
saveFileDialog.InitialDirectory = "d:\\tmp";
saveFileDialog.Filter = "Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*";
saveFileDialog.FilterIndex = 1;
saveFileDialog.RestoreDirectory = true;
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
filePath = saveFileDialog.FileName;
}
}
if (!string.IsNullOrEmpty(filePath))
{
textBoxFilePath.Text = filePath;
}
else
{
textBoxFilePath.Text = string.Empty;
}
}
private void buttonAddImage_Click(object sender, EventArgs e)
{
var filePath = string.Empty;
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.InitialDirectory = "d:\\tmp";
openFileDialog.Filter = "Image files (*.jpeg;*.jpg;*.png)|*.jpeg;*.jpg;*.png|All files (*.*)|*.*";
openFileDialog.FilterIndex = 1;
openFileDialog.RestoreDirectory = true;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
filePath = openFileDialog.FileName;
}
}
if (!string.IsNullOrEmpty(filePath))
{
listBoxImages.Items.Add(filePath);
}
}
private void buttonClearImages_Click(object sender, EventArgs e)
{
listBoxImages.Items.Clear();
}
private void buttonAddSeries_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxSeriesName.Text) || numericUpDownSeriesValue.Value == 0)
{
return;
}
ComponentExcelWithPieDiagram.ChartData chartData = new();
chartData.SeriesName = textBoxSeriesName.Text;
chartData.SeriesValue = (double)numericUpDownSeriesValue.Value;
_chartData.Add(chartData);
textBoxSeriesName.Text = string.Empty;
UpdateDataGridViewChartData();
UpdateNumericUpDownSeriesValueMaximumValue();
}
private void buttonClearSeries_Click(object sender, EventArgs e)
{
_chartData.Clear();
dataGridViewSeries.DataSource = null;
}
private void buttonCreateExcelWithPieDiagram_Click(object sender, EventArgs e)
{
LegendPosition legendPosition;
Enum.TryParse<LegendPosition>(comboBoxLegendPosition.SelectedValue.ToString(), out legendPosition);
try
{
componentExcelWithPieDiagram.CreateExcelWithPieChart(textBoxFilePath.Text, textBoxTitle.Text, textBoxDiagramTitle.Text, legendPosition, _chartData);
MessageBox.Show("Файл успешно создан", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"Ошибка при создании файла:\n{ex.Message}", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void UpdateDataGridViewChartData()
{
dataGridViewSeries.DataSource = null;
dataGridViewSeries.DataSource = _chartData;
}
private void UpdateNumericUpDownSeriesValueMaximumValue()
{
numericUpDownSeriesValue.Maximum = (decimal)(100 - _chartDataValuesSum);
numericUpDownSeriesValue.Value = numericUpDownSeriesValue.Maximum;
}
private void buttonAddEmployee_Click(object sender, EventArgs e)
{
double salary;
if (double.TryParse(textBoxSalary.Text.Replace(".", ","), out salary))
{
_employees.Add(new TableEmployee(
_employees.Count,
textBoxName.Text,
textBoxSurname.Text,
(int)numericUpDownAge.Value,
textBoxWorkPlace.Text,
textBoxPost.Text,
salary
));
UpdateTableEmployees();
}
}
private void buttonClearEmployes_Click(object sender, EventArgs e)
{
_employees.Clear();
UpdateTableEmployees();
}
private void buttonGenerateExcelWithTable_Click(object sender, EventArgs e)
{
List<(int StartRow, int EndRow, int StartCol, int EndCol, string title)> mergeCellsInfo = new List<(int StartRow, int EndRow, int StartCol, int EndCol, string title)>
{
(2, 3, 1, 1, "Личные данные"),
(5, 6, 1, 1, "Работа")
};
List<(string title, string propertyName, float height)> headersConfig = new List<(string title, string propertyName, float height)>
{
("ID", "ID", 20),
("Фамилия", "SurName", 20),
("Имя", "Name", 20),
("Возраст", "Age", 20),
("Место работы", "WorkPlace", 40),
("Должность", "WorkPost", 40),
("Зарплата", "Salary", 30)
};
try
{
componentExcelTableWithColumnHeader.GenerateExcelFile<TableEmployee>(
textBoxFilePath.Text,
textBoxTitle.Text,
mergeCellsInfo,
_employees,
headersConfig
);
MessageBox.Show("Файл успешно создан", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"Ошибка при создании файла:\n{ex.Message}", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void UpdateTableEmployees()
{
dataGridViewEmployees.DataSource = null;
dataGridViewEmployees.DataSource = _employees;
}
}
}

View File

@ -0,0 +1,129 @@
<?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>
<metadata name="componentExcelWithImage.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="componentExcelWithPieDiagram.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>256, 17</value>
</metadata>
<metadata name="componentExcelTableWithColumnHeader.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>531, 17</value>
</metadata>
</root>

View File

@ -0,0 +1,226 @@
namespace WinFormsApp
{
partial class FormVisual
{
/// <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()
{
userControlCheckedList = new Components.UserControlCheckedList();
buttonFillCheckedList = new Button();
buttonClearList = new Button();
userControlDatePicker = new Components.UserControlDatePicker();
dateTimePickerMinDate = new DateTimePicker();
dateTimePicker1 = new DateTimePicker();
label1 = new Label();
label2 = new Label();
userControlTreeView = new Components.UserControlTreeView();
buttonFillTreeView = new Button();
buttonClearTreeView = new Button();
buttonShowTreeViewNode = new Button();
textBoxTreeViewSelectedNodeIndex = new TextBox();
textBoxTreeViewSelectedObject = new TextBox();
SuspendLayout();
//
// userControlCheckedList
//
userControlCheckedList.BackColor = Color.Firebrick;
userControlCheckedList.Location = new Point(14, 16);
userControlCheckedList.Margin = new Padding(3, 5, 3, 5);
userControlCheckedList.Name = "userControlCheckedList";
userControlCheckedList.Size = new Size(192, 227);
userControlCheckedList.TabIndex = 0;
//
// buttonFillCheckedList
//
buttonFillCheckedList.Location = new Point(14, 269);
buttonFillCheckedList.Margin = new Padding(3, 4, 3, 4);
buttonFillCheckedList.Name = "buttonFillCheckedList";
buttonFillCheckedList.Size = new Size(86, 31);
buttonFillCheckedList.TabIndex = 1;
buttonFillCheckedList.Text = "Заполнить";
buttonFillCheckedList.UseVisualStyleBackColor = true;
buttonFillCheckedList.Click += buttonFillCheckedList_Click;
//
// buttonClearList
//
buttonClearList.Location = new Point(120, 269);
buttonClearList.Margin = new Padding(3, 4, 3, 4);
buttonClearList.Name = "buttonClearList";
buttonClearList.Size = new Size(86, 31);
buttonClearList.TabIndex = 2;
buttonClearList.Text = "Очистить";
buttonClearList.UseVisualStyleBackColor = true;
buttonClearList.Click += buttonClearList_Click;
//
// userControlDatePicker
//
userControlDatePicker.BackColor = Color.Orange;
userControlDatePicker.Location = new Point(312, 16);
userControlDatePicker.Margin = new Padding(3, 5, 3, 5);
userControlDatePicker.Name = "userControlDatePicker";
userControlDatePicker.Size = new Size(138, 67);
userControlDatePicker.TabIndex = 3;
//
// dateTimePickerMinDate
//
dateTimePickerMinDate.Format = DateTimePickerFormat.Short;
dateTimePickerMinDate.Location = new Point(281, 127);
dateTimePickerMinDate.Margin = new Padding(3, 4, 3, 4);
dateTimePickerMinDate.Name = "dateTimePickerMinDate";
dateTimePickerMinDate.Size = new Size(103, 27);
dateTimePickerMinDate.TabIndex = 4;
//
// dateTimePicker1
//
dateTimePicker1.Format = DateTimePickerFormat.Short;
dateTimePicker1.Location = new Point(392, 127);
dateTimePicker1.Margin = new Padding(3, 4, 3, 4);
dateTimePicker1.Name = "dateTimePicker1";
dateTimePicker1.Size = new Size(108, 27);
dateTimePicker1.TabIndex = 5;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(302, 103);
label1.Name = "label1";
label1.Size = new Size(66, 20);
label1.TabIndex = 6;
label1.Text = "MinDate";
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(413, 103);
label2.Name = "label2";
label2.Size = new Size(69, 20);
label2.TabIndex = 7;
label2.Text = "MaxDate";
//
// userControlTreeView
//
userControlTreeView.BackColor = SystemColors.ActiveCaption;
userControlTreeView.Location = new Point(569, 16);
userControlTreeView.Margin = new Padding(3, 5, 3, 5);
userControlTreeView.Name = "userControlTreeView";
userControlTreeView.SelectedIndex = -1;
userControlTreeView.Size = new Size(265, 427);
userControlTreeView.TabIndex = 8;
//
// buttonFillTreeView
//
buttonFillTreeView.Location = new Point(569, 464);
buttonFillTreeView.Margin = new Padding(3, 4, 3, 4);
buttonFillTreeView.Name = "buttonFillTreeView";
buttonFillTreeView.Size = new Size(93, 31);
buttonFillTreeView.TabIndex = 9;
buttonFillTreeView.Text = "Заполнить";
buttonFillTreeView.UseVisualStyleBackColor = true;
buttonFillTreeView.Click += buttonFillTreeView_Click;
//
// buttonClearTreeView
//
buttonClearTreeView.Location = new Point(661, 464);
buttonClearTreeView.Margin = new Padding(3, 4, 3, 4);
buttonClearTreeView.Name = "buttonClearTreeView";
buttonClearTreeView.Size = new Size(86, 31);
buttonClearTreeView.TabIndex = 10;
buttonClearTreeView.Text = "Очистить";
buttonClearTreeView.UseVisualStyleBackColor = true;
buttonClearTreeView.Click += buttonClearTreeView_Click;
//
// buttonShowTreeViewNode
//
buttonShowTreeViewNode.Location = new Point(749, 464);
buttonShowTreeViewNode.Margin = new Padding(3, 4, 3, 4);
buttonShowTreeViewNode.Name = "buttonShowTreeViewNode";
buttonShowTreeViewNode.Size = new Size(86, 31);
buttonShowTreeViewNode.TabIndex = 11;
buttonShowTreeViewNode.Text = "Показать";
buttonShowTreeViewNode.UseVisualStyleBackColor = true;
buttonShowTreeViewNode.Click += buttonShowTreeViewNode_Click;
//
// textBoxTreeViewSelectedNodeIndex
//
textBoxTreeViewSelectedNodeIndex.Location = new Point(720, 529);
textBoxTreeViewSelectedNodeIndex.Margin = new Padding(3, 4, 3, 4);
textBoxTreeViewSelectedNodeIndex.Name = "textBoxTreeViewSelectedNodeIndex";
textBoxTreeViewSelectedNodeIndex.Size = new Size(114, 27);
textBoxTreeViewSelectedNodeIndex.TabIndex = 12;
//
// textBoxTreeViewSelectedObject
//
textBoxTreeViewSelectedObject.Location = new Point(35, 529);
textBoxTreeViewSelectedObject.Margin = new Padding(3, 4, 3, 4);
textBoxTreeViewSelectedObject.Name = "textBoxTreeViewSelectedObject";
textBoxTreeViewSelectedObject.ReadOnly = true;
textBoxTreeViewSelectedObject.Size = new Size(677, 27);
textBoxTreeViewSelectedObject.TabIndex = 13;
//
// Form
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(863, 627);
Controls.Add(textBoxTreeViewSelectedObject);
Controls.Add(textBoxTreeViewSelectedNodeIndex);
Controls.Add(buttonShowTreeViewNode);
Controls.Add(buttonClearTreeView);
Controls.Add(buttonFillTreeView);
Controls.Add(userControlTreeView);
Controls.Add(label2);
Controls.Add(label1);
Controls.Add(dateTimePicker1);
Controls.Add(dateTimePickerMinDate);
Controls.Add(userControlDatePicker);
Controls.Add(buttonClearList);
Controls.Add(buttonFillCheckedList);
Controls.Add(userControlCheckedList);
Margin = new Padding(3, 4, 3, 4);
Name = "Form";
Text = "Form";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Components.UserControlCheckedList userControlCheckedList;
private Button buttonFillCheckedList;
private Button buttonClearList;
private Components.UserControlDatePicker userControlDatePicker;
private DateTimePicker dateTimePickerMinDate;
private DateTimePicker dateTimePicker1;
private Label label1;
private Label label2;
private Components.UserControlTreeView userControlTreeView;
private Button buttonFillTreeView;
private Button buttonClearTreeView;
private Button buttonShowTreeViewNode;
private TextBox textBoxTreeViewSelectedNodeIndex;
private TextBox textBoxTreeViewSelectedObject;
}
}

View File

@ -0,0 +1,92 @@
using Components.Exceptions;
namespace WinFormsApp
{
public partial class FormVisual : Form
{
public FormVisual()
{
InitializeComponent();
}
private void buttonFillCheckedList_Click(object sender, EventArgs e)
{
List<string> list = new List<string>();
list.Add("Êàæäûé");
list.Add("Ïðîãðàììèñò");
list.Add("Æåëàåò");
list.Add("Çíàòü");
list.Add("C#");
userControlCheckedList.SetCheckedListBoxValues(list);
userControlCheckedList.CheckedItem = list[3];
}
private void buttonClearList_Click(object sender, EventArgs e)
{
userControlCheckedList.ClearCheckedListBoxValues();
}
private void buttonFillTreeView_Click(object sender, EventArgs e)
{
List<Employee> employees = new List<Employee>();
employees.Add(new Employee("Îòäåë ïðîäàæ", "Ìåíåäæåð", "Èâàíîâ", "Ñåìåí"));
employees.Add(new Employee("Îòäåë ìàðêåòèíãà", "Ìàðêåòîëîã", "Êàþìîâà", "Ñâåòëàíà"));
employees.Add(new Employee("Îòäåë ôèíàíñîâ", "Áóõãàëòåð", "Ðàõèìîâà", "Ýëüâèðà"));
employees.Add(new Employee("Îòäåë çàêóïîê", "Ìåíåäæåð", "Ñåìåíîâ", "Ïåòð"));
employees.Add(new Employee("Îòäåë ïðîäàæ", "Ìåíåäæåð", "Èâàíîâ", "Ïàâåë"));
employees.Add(new Employee("Îòäåë ìàðêåòèíãà", "Ìàðêåòîëîã", "Êàðàìûøåâà", "Òàòüÿíà"));
employees.Add(new Employee("Îòäåë ôèíàíñîâ", "Ôèíàíñèñò", "Àáàëîâ", "Àëüáåðò"));
employees.Add(new Employee("Îòäåë çàêóïîê", "Ãëàâíûé ìåíåäæåð", "Ìî÷àëîâ", "Àëåêñåé"));
employees.Add(new Employee("Îòäåë ïðîäàæ", "Ãëàâíûé ìåíåäæåð", "Êóçíåöîâà", "Ìàðèÿ"));
employees.Add(new Employee("Îòäåë ìàðêåòèíãà", "PR-ñïåöèàëèñò", "Êóòÿêîâ", "Ìèõàèë"));
employees.Add(new Employee("Îòäåë ôèíàíñîâ", "Àíàëèòèê", "Àñòàôüåâ", "Ïàâåë"));
employees.Add(new Employee("Îòäåë çàêóïîê", "Àíàëèòèê", "Ñìèðíîâà", "Àíàñòàñèÿ"));
List<(string PropertyName, bool AlwaysCreateBranch)> hierarchy =
[
("Id", false),
("Departament", false),
("Position", false),
("Surname", false),
("Name", false),
];
userControlTreeView.SetHierarchy(hierarchy);
userControlTreeView.SetTreeObjects(employees);
}
private void buttonClearTreeView_Click(object sender, EventArgs e)
{
userControlTreeView.ClearTreeView();
}
private void buttonShowTreeViewNode_Click(object sender, EventArgs e)
{
Employee employee;
try
{
employee = userControlTreeView.GetObjectSelectedNode<Employee>();
textBoxTreeViewSelectedObject.Text = employee.ToString();
}
catch (PropertyNotDeclaratedException ex)
{
MessageBox.Show(ex.Message);
textBoxTreeViewSelectedObject.Text = string.Empty;
}
catch (PropertyNullException ex)
{
MessageBox.Show(ex.Message);
textBoxTreeViewSelectedObject.Text = string.Empty;
}
catch (NotSelectedNodeException ex)
{
MessageBox.Show(ex.Message);
textBoxTreeViewSelectedObject.Text = string.Empty;
}
}
}
}

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 WinFormsApp
{
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 FormNoVisual());
}
}
}

View File

@ -0,0 +1,32 @@
using System.ComponentModel;
namespace WinFormsApp
{
public class TableEmployee
{
[DisplayName("ID")]
public int ID { get; set; }
[DisplayName("Имя")]
public string Name { get; set; }
[DisplayName("Фамилия")]
public string SurName { get; set; }
[DisplayName("Возраст")]
public int Age { get; set; }
[DisplayName("Место работы")]
public string WorkPlace { get; set; }
[DisplayName("Должность")]
public string WorkPost { get; set; }
[DisplayName("Зарплата")]
public double Salary { get; set; }
public TableEmployee(int id, string name, string surname, int age, string workPlace, string workPost, double salary)
{
ID = id;
Name = name;
SurName = surname;
Age = age;
WorkPlace = workPlace;
WorkPost = workPost;
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="..\Components\Components.csproj" />
</ItemGroup>
</Project>