Compare commits

...

11 Commits

Author SHA1 Message Date
58e1420ff8 CustomListBox Fix 2024-10-03 22:08:25 +04:00
df692293b8 LabWork04 Remove IoC-container from WinFormsPlugins 2024-09-25 01:26:06 +04:00
b12ff971df LabWork04 Done 2024-09-25 01:12:58 +04:00
e1c605a649 LabWork03 is Done 2024-09-23 13:33:24 +04:00
e722d26c69 LabWork03 Debug? 2024-09-23 05:00:01 +04:00
3b73c69030 CustomTextBox Fix 2024-09-06 11:13:04 +04:00
8197103098 Fixes 2024-09-06 11:10:37 +04:00
5262be530e LabWork02 Done 2024-09-06 09:50:22 +04:00
4a4727d83a LabWork02 Bug fixes 2024-09-06 09:28:35 +04:00
ee5ec2e1a5 LabWork02 WiP 2024-09-06 04:27:34 +04:00
1d7d23e749 LabWork01 2024-09-05 18:58:41 +04:00
128 changed files with 6919 additions and 58 deletions

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\DatabaseImplement\DatabaseImplement.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,173 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
using Contracts.SearchModels;
using Contracts.StoragesContracts;
using Contracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLogics.BusinessLogics
{
/// <summary>
/// Бизнес-логика для сущности "Счет"
/// </summary>
public class OrderLogic : IOrderLogic
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Хранилище
/// </summary>
private readonly IOrderStorage _orderStorage;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="orderStorage"></param>
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage)
{
_logger = logger;
_orderStorage = orderStorage;
}
/// <summary>
/// Получить список записией
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. Order.Id: {Id}", model?.Id);
var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList. Returned null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
/// <summary>
/// Получить отдельную запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public OrderViewModel? ReadElement(OrderSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Order.Id: {Id}", model?.Id);
var element = _orderStorage.GetElement(model!);
if (element == null)
{
_logger.LogWarning("ReadElement. Element not found");
return null;
}
_logger.LogInformation("ReadElement. Find Order.Id: {Id}", element.Id);
return element;
}
/// <summary>
/// Создать запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public bool Create(OrderBindingModel model)
{
CheckModel(model);
_logger.LogInformation("Create. Order.Id: {Id}", model.Id);
if (_orderStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
/// <summary>
/// Изменить запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public bool Update(OrderBindingModel model)
{
CheckModel(model);
_logger.LogInformation("Update. Order.Id: {Id}", model.Id);
if (_orderStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
/// <summary>
/// Удалить запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public bool Delete(OrderBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Order.Id: {Id}", model.Id);
if (_orderStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
/// <summary>
/// Проверить модель
/// </summary>
/// <param name="model"></param>
/// <param name="withParams"></param>
/// <exception cref="ArgumentNullException"></exception>
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.WaiterFullName))
{
throw new ArgumentNullException("Не указано ФИО официанта", nameof(model.WaiterFullName));
}
if (string.IsNullOrEmpty(model.Info))
{
throw new ArgumentNullException("Не указана информация по счету", nameof(model.Info));
}
if (string.IsNullOrEmpty(model.Type))
{
throw new ArgumentNullException("Не указан тип заказа", nameof(model.Type));
}
_logger.LogInformation("CheckModel. Order.Id: {Id}", model.Id);
}
}
}

View File

@ -0,0 +1,165 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
using Contracts.SearchModels;
using Contracts.StoragesContracts;
using Contracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLogics.BusinessLogics
{
/// <summary>
/// Бизнес-логика для сущности "Тип заказа"
/// </summary>
public class OrderTypeLogic : IOrderTypeLogic
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Хранилище
/// </summary>
private readonly IOrderTypeStorage _orderTypeStorage;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="orderTypeStorage"></param>
public OrderTypeLogic(ILogger<OrderTypeLogic> logger, IOrderTypeStorage orderTypeStorage)
{
_logger = logger;
_orderTypeStorage = orderTypeStorage;
}
/// <summary>
/// Получить список записией
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<OrderTypeViewModel>? ReadList(OrderTypeSearchModel? model)
{
_logger.LogInformation("ReadList. OrderType.Id: {Id}", model?.Id);
var list = model == null ? _orderTypeStorage.GetFullList() : _orderTypeStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList. Returned null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
/// <summary>
/// Получить отдельную запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public OrderTypeViewModel? ReadElement(OrderTypeSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. OrderType.Id: {Id}", model?.Id);
var element = _orderTypeStorage.GetElement(model!);
if (element == null)
{
_logger.LogWarning("ReadElement. Element not found");
return null;
}
_logger.LogInformation("ReadElement. Find OrderType.Id: {Id}", element.Id);
return element;
}
/// <summary>
/// Создать запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public bool Create(OrderTypeBindingModel model)
{
CheckModel(model);
_logger.LogInformation("Create. OrderType.Id: {Id}", model.Id);
if (_orderTypeStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
/// <summary>
/// Изменить запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public bool Update(OrderTypeBindingModel model)
{
CheckModel(model);
_logger.LogInformation("Update. OrderType.Id: {Id}", model.Id);
if (_orderTypeStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
/// <summary>
/// Удалить запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public bool Delete(OrderTypeBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. OrderType.Id: {Id}", model.Id);
if (_orderTypeStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
/// <summary>
/// Проверить модель
/// </summary>
/// <param name="model"></param>
/// <param name="withParams"></param>
/// <exception cref="ArgumentNullException"></exception>
private void CheckModel(OrderTypeBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.Name))
{
throw new ArgumentNullException("Не указано название типа", nameof(model.Name));
}
_logger.LogInformation("CheckModel. OrderType.Id: {Id}", model.Id);
}
}
}

View File

@ -3,9 +3,21 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34525.116
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Components", "Components\Components.csproj", "{06211F1C-DD56-4DF0-BCBD-1F21654E1084}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Components", "Components\Components.csproj", "{06211F1C-DD56-4DF0-BCBD-1F21654E1084}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinForms", "WinForms\WinForms.csproj", "{A961BB11-3AD9-4687-B338-FCDD7887E758}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinForms", "WinForms\WinForms.csproj", "{A961BB11-3AD9-4687-B338-FCDD7887E758}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataModels", "DataModels\DataModels.csproj", "{E47EA28F-3148-4A37-BACE-35F70E297E9F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contracts", "Contracts\Contracts.csproj", "{4BA581C3-3921-4086-A41F-C507ADD258B9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DatabaseImplement", "DatabaseImplement\DatabaseImplement.csproj", "{4007A4AB-770E-4E72-8337-BC342A8C09BD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BusinessLogics", "BusinessLogics\BusinessLogics.csproj", "{324D5883-FDDE-46D1-ADF0-31D46EF95AFF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugins", "Plugins\Plugins.csproj", "{C8AE2AD4-952F-4D20-B15B-F329B30CE0FC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinFormsPlugins", "WinFormsPlugins\WinFormsPlugins.csproj", "{10BD4FBA-80C9-4B31-BE68-5A2F128F5289}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -21,6 +33,30 @@ Global
{A961BB11-3AD9-4687-B338-FCDD7887E758}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A961BB11-3AD9-4687-B338-FCDD7887E758}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A961BB11-3AD9-4687-B338-FCDD7887E758}.Release|Any CPU.Build.0 = Release|Any CPU
{E47EA28F-3148-4A37-BACE-35F70E297E9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E47EA28F-3148-4A37-BACE-35F70E297E9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E47EA28F-3148-4A37-BACE-35F70E297E9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E47EA28F-3148-4A37-BACE-35F70E297E9F}.Release|Any CPU.Build.0 = Release|Any CPU
{4BA581C3-3921-4086-A41F-C507ADD258B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4BA581C3-3921-4086-A41F-C507ADD258B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4BA581C3-3921-4086-A41F-C507ADD258B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4BA581C3-3921-4086-A41F-C507ADD258B9}.Release|Any CPU.Build.0 = Release|Any CPU
{4007A4AB-770E-4E72-8337-BC342A8C09BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4007A4AB-770E-4E72-8337-BC342A8C09BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4007A4AB-770E-4E72-8337-BC342A8C09BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4007A4AB-770E-4E72-8337-BC342A8C09BD}.Release|Any CPU.Build.0 = Release|Any CPU
{324D5883-FDDE-46D1-ADF0-31D46EF95AFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{324D5883-FDDE-46D1-ADF0-31D46EF95AFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{324D5883-FDDE-46D1-ADF0-31D46EF95AFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{324D5883-FDDE-46D1-ADF0-31D46EF95AFF}.Release|Any CPU.Build.0 = Release|Any CPU
{C8AE2AD4-952F-4D20-B15B-F329B30CE0FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C8AE2AD4-952F-4D20-B15B-F329B30CE0FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C8AE2AD4-952F-4D20-B15B-F329B30CE0FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C8AE2AD4-952F-4D20-B15B-F329B30CE0FC}.Release|Any CPU.Build.0 = Release|Any CPU
{10BD4FBA-80C9-4B31-BE68-5A2F128F5289}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10BD4FBA-80C9-4B31-BE68-5A2F128F5289}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10BD4FBA-80C9-4B31-BE68-5A2F128F5289}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10BD4FBA-80C9-4B31-BE68-5A2F128F5289}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -5,6 +5,12 @@
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Excel-DNA.Interop" Version="15.0.1" />
<PackageReference Include="Microsoft.Office.Excel" Version="14.0.4760.1000" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,36 @@
namespace Components.NonVisualComponents
{
partial class BigTextComponent
{
/// <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,81 @@
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 Components.NonVisualComponents
{
/// <summary>
/// Не визуальный компонент для создания документа Excel с большим текстом
/// </summary>
public partial class BigTextComponent : Component
{
/// <summary>
/// Конструктор
/// </summary>
public BigTextComponent()
{
InitializeComponent();
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="container"></param>
public BigTextComponent(IContainer container)
{
container.Add(this);
InitializeComponent();
}
/// <summary>
/// Создать документ
/// </summary>
/// <param name="filename"></param>
/// <param name="title"></param>
/// <param name="rows"></param>
/// <exception cref="ArgumentNullException"></exception>
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,36 @@
namespace Components.NonVisualComponents
{
partial class DiagramComponent
{
/// <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,140 @@
using Components.NonVisualComponents.HelperModels;
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 Components.NonVisualComponents
{
/// <summary>
/// Не визуальный компонент для создания документа Excel с линейной диаграммой
/// </summary>
public partial class DiagramComponent : Component
{
/// <summary>
/// Конструктор
/// </summary>
public DiagramComponent()
{
InitializeComponent();
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="container"></param>
public DiagramComponent(IContainer container)
{
container.Add(this);
InitializeComponent();
}
/// <summary>
/// Создать документ
/// </summary>
/// <param name="config"></param>
/// <exception cref="ArgumentNullException"></exception>
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,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.NonVisualComponents.HelperModels
{
/// <summary>
/// Вспомогательный класс для настройки колонки Excel
/// </summary>
public class ColumnInfo
{
/// <summary>
/// Название поля объекта
/// </summary>
public string FieldName { get; set; } = string.Empty;
/// <summary>
/// Заголовок колонки
/// </summary>
public string Header { get; set; } = string.Empty;
/// <summary>
/// Ширина колонки
/// </summary>
public int Width { get; set; }
/// <summary>
/// Конструктор
/// </summary>
/// <param name="fieldName"></param>
/// <param name="header"></param>
/// <param name="width"></param>
public ColumnInfo(string fieldName, string header, int width)
{
FieldName = fieldName;
Header = header;
Width = width;
}
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.NonVisualComponents.HelperModels
{
/// <summary>
/// Положение легенды на графике
/// </summary>
public enum LegendPosition
{
Top,
Right,
Bottom,
Left,
}
}

View File

@ -0,0 +1,41 @@
using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.NonVisualComponents.HelperModels
{
/// <summary>
/// Вспомогательный класс конфигурации для построения линейной диаграммы
/// </summary>
public class LineChartConfig
{
/// <summary>
/// Путь к файлу
/// </summary>
public string Filepath { get; set; } = string.Empty;
/// <summary>
/// Заголовок
/// </summary>
public string Header { get; set; } = string.Empty;
/// <summary>
/// Название диаграммы
/// </summary>
public string ChartTitle { get; set; } = string.Empty;
/// <summary>
/// Значения для отображения на диаграмме
/// </summary>
public Dictionary<string, List<int>> Values { get; set; } = new();
/// <summary>
/// Положение легенды на диаграмме
/// </summary>
public LegendPosition LegendPosition { get; set; }
}
}

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.NonVisualComponents.HelperModels
{
/// <summary>
/// Вспомогательный класс для объединения ячеек в Excel
/// </summary>
public class MergeCells
{
/// <summary>
/// Заголовок
/// </summary>
public string Header;
/// <summary>
/// Индексы ячеек
/// </summary>
public int[] CellIndexes;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="header"></param>
/// <param name="cellIndexes"></param>
public MergeCells(string header, int[] cellIndexes)
{
Header = header;
CellIndexes = cellIndexes;
}
}
}

View File

@ -0,0 +1,36 @@
namespace Components.NonVisualComponents
{
partial class TableComponent
{
/// <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,189 @@
using Components.NonVisualComponents.HelperModels;
using Microsoft.Office.Interop.Excel;
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 Components.NonVisualComponents
{
/// <summary>
/// Не визуальный компонент для создания документа Excel с настраиваемой таблицей
/// </summary>
public partial class TableComponent : 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' };
/// <summary>
/// Конструктор
/// </summary>
public TableComponent()
{
InitializeComponent();
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="container"></param>
public TableComponent(IContainer container)
{
container.Add(this);
InitializeComponent();
}
/// <summary>
/// Создать документ
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="filepath"></param>
/// <param name="title"></param>
/// <param name="mergeCells"></param>
/// <param name="columnsWidth"></param>
/// <param name="columns"></param>
/// <param name="headers"></param>
/// <param name="data"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="Exception"></exception>
public void CreateDocument<T>(string filepath, string title,
List<MergeCells> mergeCells, List<ColumnInfo> 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,72 @@
namespace Components.VisualComponents
{
partial class CustomComboBox
{
/// <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()
{
comboBox = new ComboBox();
labelComboBox = new Label();
SuspendLayout();
//
// comboBox
//
comboBox.Dock = DockStyle.Bottom;
comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
comboBox.FormattingEnabled = true;
comboBox.Location = new Point(0, 30);
comboBox.Name = "comboBox";
comboBox.Size = new Size(170, 23);
comboBox.TabIndex = 0;
comboBox.SelectedValueChanged += comboBox_SelectedValueChanged;
//
// labelComboBox
//
labelComboBox.AutoSize = true;
labelComboBox.Location = new Point(10, 10);
labelComboBox.Name = "labelComboBox";
labelComboBox.Size = new Size(125, 15);
labelComboBox.TabIndex = 1;
labelComboBox.Text = "Выпадающий список";
//
// CustomComboBox
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(labelComboBox);
Controls.Add(comboBox);
Name = "CustomComboBox";
Size = new Size(170, 53);
ResumeLayout(false);
PerformLayout();
}
#endregion
private ComboBox comboBox;
private Label labelComboBox;
}
}

View File

@ -0,0 +1,107 @@
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 Components.VisualComponents
{
/// <summary>
/// Визуальный компонент для выбора из выпадающего списка
/// </summary>
public partial class CustomComboBox : UserControl
{
/// <summary>
/// Событие, вызываемое при смене значения
/// </summary>
private EventHandler _onValueChangedEvent;
/// <summary>
/// Событие, вызываемое при смене значения
/// </summary>
public event EventHandler ValueChanged
{
add
{
_onValueChangedEvent += value;
}
remove
{
_onValueChangedEvent -= value;
}
}
/// <summary>
/// Выбранный элемент
/// </summary>
public string SelectedItem
{
get
{
if (comboBox.Items.Count == 0)
{
return "";
}
if (comboBox.SelectedItem == null)
{
return "";
}
return comboBox.SelectedItem.ToString()!;
}
set
{
if (comboBox.Items.Contains(value))
{
comboBox.SelectedItem = value;
}
}
}
/// <summary>
/// Конструктор
/// </summary>
public CustomComboBox()
{
InitializeComponent();
}
/// <summary>
/// Добавить элемент
/// </summary>
/// <param name="item"></param>
public void AddItem(string item)
{
if (item == null)
{
return;
}
comboBox.Items.Add(item);
}
/// <summary>
/// Очистить список
/// </summary>
public void Clear()
{
comboBox.Items.Clear();
}
/// <summary>
/// Смена значения
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void comboBox_SelectedValueChanged(object sender, EventArgs e)
{
_onValueChangedEvent?.Invoke(sender, e);
}
}
}

View File

@ -0,0 +1,58 @@
namespace Components.VisualComponents
{
partial class CustomListBox
{
/// <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()
{
listBox = new ListBox();
SuspendLayout();
//
// listBox
//
listBox.Dock = DockStyle.Fill;
listBox.FormattingEnabled = true;
listBox.ItemHeight = 15;
listBox.Location = new Point(0, 0);
listBox.Name = "listBox";
listBox.Size = new Size(300, 150);
listBox.TabIndex = 0;
//
// CustomListBox
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(listBox);
Name = "CustomListBox";
Size = new Size(300, 150);
ResumeLayout(false);
}
#endregion
private ListBox listBox;
}
}

View File

@ -0,0 +1,147 @@
using Components.VisualComponents.HelperModels;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Components.VisualComponents
{
/// <summary>
/// Визуальный компонент для вывода списка в виде списка записей
/// </summary>
public partial class CustomListBox : UserControl
{
/// <summary>
/// Конфигурация
/// </summary>
private CustomListBoxConfig _config;
/// <summary>
/// Индекс выбранной строки
/// </summary>
public int SelectedIndex
{
get
{
return listBox.SelectedIndex;
}
set
{
if (listBox.SelectedItems.Count != 0)
{
listBox.SelectedIndex = value;
}
}
}
/// <summary>
/// Конструктор
/// </summary>
public CustomListBox()
{
InitializeComponent();
}
/// <summary>
/// Задать конфигурацию
/// </summary>
/// <param name="config"></param>
/// <exception cref="Exception"></exception>
public void SetConfig(CustomListBoxConfig config)
{
if (_config != null)
{
throw new Exception("Конфигурация уже задана!");
}
if (string.IsNullOrEmpty(config.LayoutString) || string.IsNullOrEmpty(config.StartSymbol) || string.IsNullOrEmpty(config.EndSymbol))
{
throw new Exception("Заполните макетную строку!");
}
if (!config.LayoutString.Contains(config.StartSymbol) || !config.LayoutString.Contains(config.EndSymbol))
{
throw new Exception("Макетная строка не содержит нужные элементы!");
}
_config = config;
}
/// <summary>
/// Получить объект из выбранной строки
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T? GetObject<T>() where T : class, new()
{
if (listBox.SelectedIndex == -1 || _config == null)
{
return null;
}
string selectedString = listBox.SelectedItem.ToString()!;
string layoutString = _config.LayoutString;
T obj = new T();
string[] layoutParts = Regex.Split(layoutString, _config.Pattern);
for (int i = 0; i < layoutParts.Length - 1; i++)
{
int startPosition;
string matchedText = GetSubstring(layoutParts[i], layoutParts[i + 1], selectedString, out startPosition);
selectedString = selectedString.Remove(0, startPosition + matchedText.Length);
string patternSegment = GetSubstring(layoutParts[i], layoutParts[i + 1], layoutString, out startPosition);
layoutString = layoutString.Remove(0, startPosition + patternSegment.Length);
patternSegment = patternSegment.Substring(1, patternSegment.Length - 2);
PropertyInfo property = obj.GetType().GetProperty(patternSegment);
property?.SetValue(obj, Convert.ChangeType(matchedText, property?.PropertyType));
}
return obj;
}
/// <summary>
/// Добавить объект в список
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="Exception"></exception>
public void AddObject<T>(T obj)
{
if (obj == null)
{
throw new ArgumentNullException("Добавляемый объект не существует!");
}
if (_config == null)
{
throw new Exception("Конфигурация не задана!");
}
string processedString = _config.LayoutString;
MatchCollection matchCollection = Regex.Matches(_config.LayoutString, _config.Pattern);
foreach (Match item in matchCollection)
{
string propertyName = item.Value.Remove(item.Value.Length - 1, 1).Remove(0, 1);
processedString = processedString.Replace($"{_config.StartSymbol}{propertyName}{_config.EndSymbol}", obj.GetType().GetProperty(propertyName)?.GetValue(obj, null)?.ToString());
}
listBox.Items.Add(processedString);
}
private string GetSubstring(string startDelimiter, string endDelimiter, string baseString, out int startPosition)
{
startPosition = startDelimiter.Length;
int endPosition = baseString.IndexOf(endDelimiter) - 1;
endPosition = (endPosition >= startPosition) ? endPosition : (baseString.Length - 1);
return baseString.Substring(startPosition, endPosition - startPosition + 1);
}
}
}

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,71 @@
namespace Components.VisualComponents
{
partial class CustomTextBox
{
/// <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()
{
textBox = new TextBox();
label = new Label();
SuspendLayout();
//
// textBox
//
textBox.Dock = DockStyle.Bottom;
textBox.Location = new Point(0, 30);
textBox.Name = "textBox";
textBox.Size = new Size(170, 23);
textBox.TabIndex = 0;
textBox.TextChanged += textBox_TextChanged;
textBox.Enter += textBox_Enter;
//
// label
//
label.AutoSize = true;
label.Location = new Point(10, 10);
label.Name = "label";
label.Size = new Size(32, 15);
label.TabIndex = 1;
label.Text = "Дата";
//
// CustomTextBox
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(label);
Controls.Add(textBox);
Name = "CustomTextBox";
Size = new Size(170, 53);
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBox;
private Label label;
}
}

View File

@ -0,0 +1,142 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using Components.VisualComponents.Exceptions;
namespace Components.VisualComponents
{
/// <summary>
/// Текстовый визуальный компонент для ввода значения с проверкой по шаблону
/// </summary>
public partial class CustomTextBox : UserControl
{
/// <summary>
/// Шаблон вводимого значения
/// </summary>
private string? _datePattern;
/// <summary>
/// Шаблон вводимого значения
/// </summary>
public string? DatePattern
{
get { return _datePattern; }
set { _datePattern = value; }
}
/// <summary>
/// Пример вводимого значения
/// </summary>
private string _dateExample = "01.01.1970";
/// <summary>
/// Введенное значение
/// </summary>
public string? TextBoxValue
{
get
{
if (DatePattern == null)
{
throw new NullPatternException("Шаблон не заполнен!");
}
Regex regex = new Regex(DatePattern);
bool isValid = regex.IsMatch(textBox.Text);
if (isValid)
{
return textBox.Text;
}
else
{
throw new InvalidInputException(textBox.Text);
}
}
set
{
Regex regex = new Regex(DatePattern!);
bool isValid = regex.IsMatch(value);
if (isValid)
{
textBox.Text = value;
}
}
}
/// <summary>
/// Событие, вызываемое при смене значения
/// </summary>
private EventHandler _onValueChangedEvent;
/// <summary>
/// Событие, вызываемое при смене значения
/// </summary>
public event EventHandler ValueChanged
{
add
{
_onValueChangedEvent += value;
}
remove
{
_onValueChangedEvent -= value;
}
}
/// <summary>
/// Конструктор
/// </summary>
public CustomTextBox()
{
InitializeComponent();
}
/// <summary>
/// Заполнить пример вводимого значения
/// </summary>
/// <param name="date"></param>
public bool SetDateExample(string date)
{
Regex regex = new Regex(DatePattern!);
bool isValid = regex.IsMatch(date);
if (isValid)
{
_dateExample = date;
return true;
}
return false;
}
/// <summary>
/// Вывод подсказки с примером правильного ввода
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void textBox_Enter(object sender, EventArgs e)
{
int visibleTime = 2000;
ToolTip tooltip = new ToolTip();
tooltip.Show(_dateExample, textBox, 30, -20, visibleTime);
}
/// <summary>
/// Смена значения
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void textBox_TextChanged(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,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.VisualComponents.Exceptions
{
/// <summary>
/// Исключение, вызываемое, когда введенное значение не соответствует шаблону
/// </summary>
public class InvalidInputException : Exception
{
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public InvalidInputException() { }
/// <summary>
/// Констурктор с сообщением
/// </summary>
/// <param name="message"></param>
public InvalidInputException(string message) : base($"{message} не соответствует шаблону!") { }
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.VisualComponents.Exceptions
{
/// <summary>
/// Исключение, вызываемое, когда шаблон не установлен
/// </summary>
public class NullPatternException : Exception
{
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public NullPatternException() { }
/// <summary>
/// Констурктор с сообщением
/// </summary>
/// <param name="message"></param>
public NullPatternException(string message) : base(message) { }
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.VisualComponents.HelperModels
{
/// <summary>
/// Вспомогательный класс конфигурации для CustomListBox
/// </summary>
public class CustomListBoxConfig
{
/// <summary>
/// Макетная строка
/// </summary>
public string LayoutString { get; set; } = string.Empty;
/// <summary>
/// Символ начала имени свойства
/// </summary>
public string StartSymbol { get; set; } = string.Empty;
/// <summary>
/// Символ конца имени свойства
/// </summary>
public string EndSymbol { get; set; } = string.Empty;
/// <summary>
/// Паттерн записи свойства
/// </summary>
public string Pattern => $"{StartSymbol}{"[\\w]+"}{EndSymbol}";
}
}

View File

@ -0,0 +1,40 @@
using DataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.BindingModels
{
/// <summary>
/// Модель привязки для сущности "Счет"
/// </summary>
public class OrderBindingModel : IOrderModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; set; }
/// <summary>
/// ФИО официанта
/// </summary>
public string WaiterFullName { get; set; } = string.Empty;
/// <summary>
/// Информация по счету
/// </summary>
public string Info { get; set; } = string.Empty;
/// <summary>
/// Тип заказа
/// </summary>
public string Type { get; set; } = string.Empty;
/// <summary>
/// Сумма заказа
/// </summary>
public double? Sum { get; set; }
}
}

View File

@ -0,0 +1,25 @@
using DataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.BindingModels
{
/// <summary>
/// Модель привязки для сущности "Тип заказа"
/// </summary>
public class OrderTypeBindingModel : IOrderTypeModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; set; }
/// <summary>
/// Название типа
/// </summary>
public string Name { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,52 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.BusinessLogicsContracts
{
/// <summary>
/// Интерфейс для описания работы бизнес-логики для сущности "Счет"
/// </summary>
public interface IOrderLogic
{
/// <summary>
/// Получить список записией
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
List<OrderViewModel>? ReadList(OrderSearchModel? model);
/// <summary>
/// Получить отдельную запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
OrderViewModel? ReadElement(OrderSearchModel model);
/// <summary>
/// Создать запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
bool Create(OrderBindingModel model);
/// <summary>
/// Изменить запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
bool Update(OrderBindingModel model);
/// <summary>
/// Удалить запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
bool Delete(OrderBindingModel model);
}
}

View File

@ -0,0 +1,52 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.BusinessLogicsContracts
{
/// <summary>
/// Интерфейс для описания работы бизнес-логики для сущности "Тип заказа"
/// </summary>
public interface IOrderTypeLogic
{
/// <summary>
/// Получить список записией
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
List<OrderTypeViewModel>? ReadList(OrderTypeSearchModel? model);
/// <summary>
/// Получить отдельную запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
OrderTypeViewModel? ReadElement(OrderTypeSearchModel model);
/// <summary>
/// Создать запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
bool Create(OrderTypeBindingModel model);
/// <summary>
/// Изменить запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
bool Update(OrderTypeBindingModel model);
/// <summary>
/// Удалить запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
bool Delete(OrderTypeBindingModel model);
}
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DataModels\DataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.SearchModels
{
/// <summary>
/// Модель поиска для сущности "Счет"
/// </summary>
public class OrderSearchModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int? Id { get; set; }
/// <summary>
/// ФИО официанта
/// </summary>
public string? WaiterFullName { get; set; }
/// <summary>
/// Тип заказа
/// </summary>
public string? Type { get; set; }
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.SearchModels
{
/// <summary>
/// Модель поиска для сущности "Тип заказа"
/// </summary>
public class OrderTypeSearchModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int? Id { get; set; }
/// <summary>
/// Название типа
/// </summary>
public string? Name { get; set; }
}
}

View File

@ -0,0 +1,58 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.StoragesContracts
{
/// <summary>
/// Интерфейс для описания работы с хранилищем для сущности "Счет"
/// </summary>
public interface IOrderStorage
{
/// <summary>
/// Получить полный список элементов
/// </summary>
/// <returns></returns>
List<OrderViewModel> GetFullList();
/// <summary>
/// Получить фильтрованный список элементов
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
List<OrderViewModel> GetFilteredList(OrderSearchModel model);
/// <summary>
/// Получить элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
OrderViewModel? GetElement(OrderSearchModel model);
/// <summary>
/// Добавить элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
OrderViewModel? Insert(OrderBindingModel model);
/// <summary>
/// Редактировать элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
OrderViewModel? Update(OrderBindingModel model);
/// <summary>
/// Удалить элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
OrderViewModel? Delete(OrderBindingModel model);
}
}

View File

@ -0,0 +1,58 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.StoragesContracts
{
/// <summary>
/// Интерфейс для описания работы с хранилищем для сущности "Тип заказа"
/// </summary>
public interface IOrderTypeStorage
{
/// <summary>
/// Получить полный список элементов
/// </summary>
/// <returns></returns>
List<OrderTypeViewModel> GetFullList();
/// <summary>
/// Получить фильтрованный список элементов
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
List<OrderTypeViewModel> GetFilteredList(OrderTypeSearchModel model);
/// <summary>
/// Получить элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
OrderTypeViewModel? GetElement(OrderTypeSearchModel model);
/// <summary>
/// Добавить элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
OrderTypeViewModel? Insert(OrderTypeBindingModel model);
/// <summary>
/// Редактировать элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
OrderTypeViewModel? Update(OrderTypeBindingModel model);
/// <summary>
/// Удалить элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
OrderTypeViewModel? Delete(OrderTypeBindingModel model);
}
}

View File

@ -0,0 +1,27 @@
using DataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.ViewModels
{
/// <summary>
/// Модель отображения для сущности "Тип заказа"
/// </summary>
public class OrderTypeViewModel : IOrderTypeModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; set; }
/// <summary>
/// Название типа
/// </summary>
[DisplayName("Тип заказа")]
public string Name { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,45 @@
using DataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.ViewModels
{
/// <summary>
/// Модель отображения для сущности "Счет"
/// </summary>
public class OrderViewModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; set; }
/// <summary>
/// ФИО официанта
/// </summary>
[DisplayName("ФИО официанта")]
public string WaiterFullName { get; set; } = string.Empty;
/// <summary>
/// Информация по счету
/// </summary>
[DisplayName("Информация")]
public string Info { get; set; } = string.Empty;
/// <summary>
/// Тип заказа
/// </summary>
[DisplayName("Тип заказа")]
public string Type { get; set; } = string.Empty;
/// <summary>
/// Сумма заказа
/// </summary>
[DisplayName("Сумма заказа")]
public string? Sum { get; set; }
}
}

View File

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

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataModels
{
/// <summary>
/// Интерфейс для идентификатора
/// </summary>
public interface IId
{
/// <summary>
/// Идентификатор
/// </summary>
int Id { get; }
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataModels.Models
{
/// <summary>
/// Интерфейс для сущности "Счет"
/// </summary>
public interface IOrderModel : IId
{
/// <summary>
/// ФИО официанта
/// </summary>
string WaiterFullName { get; }
/// <summary>
/// Информация по счету
/// </summary>
string Info { get; }
/// <summary>
/// Тип заказа
/// </summary>
string Type { get; }
/// <summary>
/// Сумма заказа
/// </summary>
double? Sum { get; }
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataModels.Models
{
/// <summary>
/// Интерфейс для сущности "Тип заказа"
/// </summary>
public interface IOrderTypeModel : IId
{
/// <summary>
/// Название типа
/// </summary>
string Name { get; }
}
}

View File

@ -0,0 +1,44 @@
using DatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement
{
/// <summary>
/// Класс для взаимодействия с базой данных
/// </summary>
public class Database : DbContext
{
/// <summary>
/// Параметры подключения к базе данных
/// </summary>
private string _dbConnectionString = "Host=localhost;Port=5432;Database=COPLabWorks;Username=postgres;Password=2004";
/// <summary>
/// Подключение к базе данных
/// </summary>
/// <param name="optionsBuilder"></param>
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (optionsBuilder.IsConfigured == false)
{
optionsBuilder.UseNpgsql(_dbConnectionString);
}
base.OnConfiguring(optionsBuilder);
}
/// <summary>
/// Таблица "Счета"
/// </summary>
public virtual DbSet<Order> Orders { get; set; }
/// <summary>
/// Таблица "Типы заказов"
/// </summary>
public virtual DbSet<OrderType> OrderTypes { get; set; }
}
}

View File

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.13">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contracts\Contracts.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,137 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.StoragesContracts;
using Contracts.ViewModels;
using DatabaseImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement.Implements
{
/// <summary>
/// Хранилище для сущности "Счет"
/// </summary>
public class OrderStorage : IOrderStorage
{
/// <summary>
/// Получить полный список элементов
/// </summary>
/// <returns></returns>
public List<OrderViewModel> GetFullList()
{
using var context = new Database();
return context.Orders
.Select(x => x.GetViewModel)
.ToList();
}
/// <summary>
/// Получить фильтрованный список элементов
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
using var context = new Database();
// Фильтрация по ФИО официанта
if (!string.IsNullOrEmpty(model.WaiterFullName))
{
return context.Orders
.Where(x => x.WaiterFullName.Contains(model.WaiterFullName))
.Select(x => x.GetViewModel)
.ToList();
}
// Фильтрация по типу заказа
if (!string.IsNullOrEmpty(model.Type))
{
return context.Orders
.Where(x => x.Type.Contains(model.Type))
.Select(x => x.GetViewModel)
.ToList();
}
return new();
}
/// <summary>
/// Получить элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public OrderViewModel? GetElement(OrderSearchModel model)
{
using var context = new Database();
if (model.Id.HasValue)
{
return context.Orders
.FirstOrDefault(x => x.Id.Equals(model.Id))
?.GetViewModel;
}
return null;
}
/// <summary>
/// Добавить элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public OrderViewModel? Insert(OrderBindingModel model)
{
using var context = new Database();
var newOrder = Order.Create(model);
if (newOrder == null)
{
return null;
}
context.Orders.Add(newOrder);
context.SaveChanges();
return newOrder.GetViewModel;
}
/// <summary>
/// Редактировать элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public OrderViewModel? Update(OrderBindingModel model)
{
using var context = new Database();
var order = context.Orders
.FirstOrDefault(x => x.Id.Equals(model.Id));
if (order == null)
{
return null;
}
order.Update(model);
context.SaveChanges();
return order.GetViewModel;
}
/// <summary>
/// Удалить элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public OrderViewModel? Delete(OrderBindingModel model)
{
using var context = new Database();
var order = context.Orders
.FirstOrDefault(x => x.Id.Equals(model.Id));
if (order == null)
{
return null;
}
context.Orders.Remove(order);
context.SaveChanges();
return order.GetViewModel;
}
}
}

View File

@ -0,0 +1,128 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.StoragesContracts;
using Contracts.ViewModels;
using DatabaseImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement.Implements
{
/// <summary>
/// Хранилище для сущности "Тип заказа"
/// </summary>
public class OrderTypeStorage : IOrderTypeStorage
{
/// <summary>
/// Получить полный список элементов
/// </summary>
/// <returns></returns>
public List<OrderTypeViewModel> GetFullList()
{
using var context = new Database();
return context.OrderTypes
.Select(x => x.GetViewModel)
.ToList();
}
/// <summary>
/// Получить фильтрованный список элементов
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<OrderTypeViewModel> GetFilteredList(OrderTypeSearchModel model)
{
using var context = new Database();
// Фильтрация по названию типа
if (!string.IsNullOrEmpty(model.Name))
{
return context.OrderTypes
.Where(x => x.Name.Contains(model.Name))
.Select(x => x.GetViewModel)
.ToList();
}
return new();
}
/// <summary>
/// Получить элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public OrderTypeViewModel? GetElement(OrderTypeSearchModel model)
{
using var context = new Database();
if (model.Id.HasValue)
{
return context.OrderTypes
.FirstOrDefault(x => x.Id.Equals(model.Id))
?.GetViewModel;
}
return null;
}
/// <summary>
/// Добавить элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public OrderTypeViewModel? Insert(OrderTypeBindingModel model)
{
using var context = new Database();
var newOrderType = OrderType.Create(model);
if (newOrderType == null)
{
return null;
}
context.OrderTypes.Add(newOrderType);
context.SaveChanges();
return newOrderType.GetViewModel;
}
/// <summary>
/// Редактировать элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public OrderTypeViewModel? Update(OrderTypeBindingModel model)
{
using var context = new Database();
var orderType = context.OrderTypes
.FirstOrDefault(x => x.Id.Equals(model.Id));
if (orderType == null)
{
return null;
}
orderType.Update(model);
context.SaveChanges();
return orderType.GetViewModel;
}
/// <summary>
/// Удалить элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public OrderTypeViewModel? Delete(OrderTypeBindingModel model)
{
using var context = new Database();
var orderType = context.OrderTypes
.FirstOrDefault(x => x.Id.Equals(model.Id));
if (orderType == null)
{
return null;
}
context.OrderTypes.Remove(orderType);
context.SaveChanges();
return orderType.GetViewModel;
}
}
}

View File

@ -0,0 +1,75 @@
// <auto-generated />
using System;
using DatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace DatabaseImplement.Migrations
{
[DbContext(typeof(Database))]
[Migration("20240920214214_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.13")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("DatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Info")
.IsRequired()
.HasColumnType("text");
b.Property<double?>("Sum")
.HasColumnType("double precision");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.Property<string>("WaiterFullName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Orders");
});
modelBuilder.Entity("DatabaseImplement.Models.OrderType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("OrderTypes");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,54 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace DatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Orders",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
WaiterFullName = table.Column<string>(type: "text", nullable: false),
Info = table.Column<string>(type: "text", nullable: false),
Type = table.Column<string>(type: "text", nullable: false),
Sum = table.Column<double>(type: "double precision", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Orders", x => x.Id);
});
migrationBuilder.CreateTable(
name: "OrderTypes",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_OrderTypes", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Orders");
migrationBuilder.DropTable(
name: "OrderTypes");
}
}
}

View File

@ -0,0 +1,72 @@
// <auto-generated />
using System;
using DatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace DatabaseImplement.Migrations
{
[DbContext(typeof(Database))]
partial class DatabaseModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.13")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("DatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Info")
.IsRequired()
.HasColumnType("text");
b.Property<double?>("Sum")
.HasColumnType("double precision");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.Property<string>("WaiterFullName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Orders");
});
modelBuilder.Entity("DatabaseImplement.Models.OrderType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("OrderTypes");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,97 @@
using Contracts.BindingModels;
using Contracts.ViewModels;
using DataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement.Models
{
/// <summary>
/// Сущность "Счет"
/// </summary>
public class Order : IOrderModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; private set; }
/// <summary>
/// ФИО водителя
/// </summary>
[Required]
public string WaiterFullName { get; private set; } = string.Empty;
/// <summary>
/// Информация по счету
/// </summary>
[Required]
public string Info { get; private set; } = string.Empty;
/// <summary>
/// Тип заказа
/// </summary>
[Required]
public string Type { get; private set; } = string.Empty;
/// <summary>
/// Сумма заказа
/// </summary>
public double? Sum { get; private set; }
/// <summary>
/// Создать модель
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public static Order? Create(OrderBindingModel model)
{
if (model == null)
{
return null;
}
return new Order
{
Id = model.Id,
WaiterFullName = model.WaiterFullName,
Info = model.Info,
Type = model.Type,
Sum = model.Sum,
};
}
/// <summary>
/// Изменить модель
/// </summary>
/// <param name="model"></param>
public void Update(OrderBindingModel model)
{
if (model == null)
{
return;
}
WaiterFullName = model.WaiterFullName;
Info = model.Info;
Type = model.Type;
Sum = model.Sum;
}
/// <summary>
/// Получить модель отображения
/// </summary>
public OrderViewModel GetViewModel => new()
{
Id = Id,
WaiterFullName = WaiterFullName,
Info = Info,
Type = Type,
Sum = Sum.ToString(),
};
}
}

View File

@ -0,0 +1,89 @@
using Contracts.BindingModels;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement.Models
{
/// <summary>
/// Сущность "Тип заказа"
/// </summary>
public class OrderType
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; private set; }
/// <summary>
/// Название типа
/// </summary>
[Required]
public string Name { get; private set; } = string.Empty;
/// <summary>
/// Создать модель
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public static OrderType? Create(OrderTypeBindingModel model)
{
if (model == null)
{
return null;
}
return new OrderType
{
Id = model.Id,
Name = model.Name,
};
}
/// <summary>
/// Создать модель
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public static OrderType? Create(OrderTypeViewModel model)
{
if (model == null)
{
return null;
}
return new OrderType
{
Id = model.Id,
Name = model.Name,
};
}
/// <summary>
/// Изменить модель
/// </summary>
/// <param name="model"></param>
public void Update(OrderTypeBindingModel model)
{
if (model == null)
{
return;
}
Name = model.Name;
}
/// <summary>
/// Получить модель отображения
/// </summary>
public OrderTypeViewModel GetViewModel => new()
{
Id = Id,
Name = Name,
};
}
}

View File

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Plugins
{
/// <summary>
/// Интерфейс-соглашение для плагинов
/// </summary>
public interface IPluginsConvention
{
/// <summary>
/// Название плагина
/// </summary>
string PluginName { get; }
/// <summary>
/// Получение контрола для вывода набора данных
/// </summary>
UserControl GetControl { get; }
/// <summary>
/// Получение элемента, выбранного в контроле
/// </summary>
PluginsConventionElement GetElement { get; }
/// <summary>
/// Получение формы для создания/редактирования объекта
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
Form GetForm(PluginsConventionElement element);
/// <summary>
/// Получение формы для работы со справочником
/// </summary>
/// <returns></returns>
Form GetThesaurus();
/// <summary>
/// Удаление элемента
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
bool DeleteElement(PluginsConventionElement element);
/// <summary>
/// Обновление набора данных в контроле
/// </summary>
void ReloadData();
/// <summary>
/// Создание простого документа
/// </summary>
/// <param name="saveDocument"></param>
/// <returns></returns>
bool CreateSimpleDocument(PluginsConventionSaveDocument saveDocument);
/// <summary>
/// Создание документа с настраиваемой таблицей
/// </summary>
/// <param name="saveDocument"></param>
/// <returns></returns>
bool CreateTableDocument(PluginsConventionSaveDocument saveDocument);
/// <summary>
/// Создание документа с диаграммой
/// </summary>
/// <param name="saveDocument"></param>
/// <returns></returns>
bool CreateChartDocument(PluginsConventionSaveDocument saveDocument);
}
}

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>

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Plugins
{
/// <summary>
/// Класс для передачи объекта на форму и удаления
/// </summary>
public class PluginsConventionElement
{
/// <summary>
/// Глобальный уникальный идентификатор
/// </summary>
public Guid Id { 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 Plugins
{
/// <summary>
/// Класс для передачи данных в методы создания документов
/// </summary>
public class PluginsConventionSaveDocument
{
/// <summary>
/// Путь к файлу
/// </summary>
public string FileName { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinForms.DataModels
{
/// <summary>
/// Сущность "Человек"
/// </summary>
public class Employee
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; set; }
/// <summary>
/// Статус
/// </summary>
public string Status { get; set; }
/// <summary>
/// Имя
/// </summary>
public string Name { get; set; }
/// <summary>
/// Фамилия
/// </summary>
public string Surname { get; set; }
/// <summary>
/// Возраст
/// </summary>
public int Age { get; set; }
/// <summary>
/// Наличие детей
/// </summary>
public string Kids { get; set; }
/// <summary>
/// Наличие личного автомобиля
/// </summary>
public string Car { get; set; }
/// <summary>
/// Подразделение
/// </summary>
public string Department { get; set; }
/// <summary>
/// Должность
/// </summary>
public string Post { get; set; }
/// <summary>
/// Премия
/// </summary>
public double Prize { get; set; }
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public Employee() { }
/// <summary>
/// Конструктор с параметрами
/// </summary>
/// <param name="id"></param>
/// <param name="status"></param>
/// <param name="name"></param>
/// <param name="surname"></param>
/// <param name="age"></param>
/// <param name="kids"></param>
/// <param name="car"></param>
/// <param name="department"></param>
/// <param name="post"></param>
/// <param name="prize"></param>
public Employee(int id, string status, string name, string surname, int age, string kids, string car, string department, string post, double prize)
{
Id = id;
Status = status;
Name = name;
Surname = surname;
Age = age;
Kids = kids;
Car = car;
Department = department;
Post = post;
Prize = prize;
}
}
}

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinForms.DataModels
{
/// <summary>
/// Сущность "Человек"
/// </summary>
public class Person
{
/// <summary>
/// Имя
/// </summary>
public string Name { get; set; }
/// <summary>
/// Фамилия
/// </summary>
public string Surname { get; set; }
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public Person() { }
/// <summary>
/// Конструктор с параметрами
/// </summary>
/// <param name="name"></param>
/// <param name="surname"></param>
public Person(string name, string surname)
{
Name = name;
Surname = surname;
}
}
}

View File

@ -1,45 +0,0 @@
namespace WinForms
{
partial class FormComponents
{
/// <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()
{
SuspendLayout();
//
// FormComponents
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Name = "FormComponents";
Text = "Компоненты";
ResumeLayout(false);
}
#endregion
}
}

View File

@ -1,10 +0,0 @@
namespace WinForms
{
public partial class FormComponents : Form
{
public FormComponents()
{
InitializeComponent();
}
}
}

141
Components/WinForms/FormMain.Designer.cs generated Normal file
View File

@ -0,0 +1,141 @@
namespace WinForms
{
partial class FormMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
contextMenuStrip = new ContextMenuStrip(components);
createElementToolStripMenuItem = new ToolStripMenuItem();
updateElementToolStripMenuItem = new ToolStripMenuItem();
deleteElementToolStripMenuItem = new ToolStripMenuItem();
createWordDocumentToolStripMenuItem = new ToolStripMenuItem();
createExcelDocumentToolStripMenuItem = new ToolStripMenuItem();
createPdfDocumentToolStripMenuItem = new ToolStripMenuItem();
orderTypesToolStripMenuItem = new ToolStripMenuItem();
userTreeView = new ComponentsLibrary.VisualComponents.UserTreeView();
componentDocumentWithTableMultiHeaderWord1 = new ComponentsLibraryNet60.DocumentWithTable.ComponentDocumentWithTableMultiHeaderWord(components);
bigTextComponent1 = new Components.NonVisualComponents.BigTextComponent(components);
pdfPieChart1 = new ComponentsLibrary.NonVisualComponents.PdfPieChart(components);
contextMenuStrip.SuspendLayout();
SuspendLayout();
//
// contextMenuStrip
//
contextMenuStrip.Items.AddRange(new ToolStripItem[] { createElementToolStripMenuItem, updateElementToolStripMenuItem, deleteElementToolStripMenuItem, createWordDocumentToolStripMenuItem, createExcelDocumentToolStripMenuItem, createPdfDocumentToolStripMenuItem, orderTypesToolStripMenuItem });
contextMenuStrip.Name = "contextMenuStrip";
contextMenuStrip.Size = new Size(205, 158);
contextMenuStrip.Text = "Контекстное меню";
//
// createElementToolStripMenuItem
//
createElementToolStripMenuItem.Name = "createElementToolStripMenuItem";
createElementToolStripMenuItem.Size = new Size(204, 22);
createElementToolStripMenuItem.Text = "Добавить запись";
createElementToolStripMenuItem.Click += createElementToolStripMenuItem_Click;
//
// updateElementToolStripMenuItem
//
updateElementToolStripMenuItem.Name = "updateElementToolStripMenuItem";
updateElementToolStripMenuItem.Size = new Size(204, 22);
updateElementToolStripMenuItem.Text = "Редактировать запись";
updateElementToolStripMenuItem.Click += updateElementToolStripMenuItem_Click;
//
// deleteElementToolStripMenuItem
//
deleteElementToolStripMenuItem.Name = "deleteElementToolStripMenuItem";
deleteElementToolStripMenuItem.Size = new Size(204, 22);
deleteElementToolStripMenuItem.Text = "Удалить запись";
deleteElementToolStripMenuItem.Click += deleteElementToolStripMenuItem_Click;
//
// createWordDocumentToolStripMenuItem
//
createWordDocumentToolStripMenuItem.Name = "createWordDocumentToolStripMenuItem";
createWordDocumentToolStripMenuItem.Size = new Size(204, 22);
createWordDocumentToolStripMenuItem.Text = "Создать документ Word";
createWordDocumentToolStripMenuItem.Click += createWordDocumentToolStripMenuItem_Click;
//
// createExcelDocumentToolStripMenuItem
//
createExcelDocumentToolStripMenuItem.Name = "createExcelDocumentToolStripMenuItem";
createExcelDocumentToolStripMenuItem.Size = new Size(204, 22);
createExcelDocumentToolStripMenuItem.Text = "Создать документ Excel";
createExcelDocumentToolStripMenuItem.Click += createExcelDocumentToolStripMenuItem_Click;
//
// createPdfDocumentToolStripMenuItem
//
createPdfDocumentToolStripMenuItem.Name = "createPdfDocumentToolStripMenuItem";
createPdfDocumentToolStripMenuItem.Size = new Size(204, 22);
createPdfDocumentToolStripMenuItem.Text = " Создать документ Pdf";
createPdfDocumentToolStripMenuItem.Click += createPdfDocumentToolStripMenuItem_Click;
//
// orderTypesToolStripMenuItem
//
orderTypesToolStripMenuItem.Name = "orderTypesToolStripMenuItem";
orderTypesToolStripMenuItem.Size = new Size(204, 22);
orderTypesToolStripMenuItem.Text = "Типы заказов";
orderTypesToolStripMenuItem.Click += orderTypesToolStripMenuItem_Click;
//
// userTreeView
//
userTreeView.Dock = DockStyle.Fill;
userTreeView.Location = new Point(0, 0);
userTreeView.Margin = new Padding(3, 2, 3, 2);
userTreeView.Name = "userTreeView";
userTreeView.SelectedNodeIndex = -1;
userTreeView.Size = new Size(800, 450);
userTreeView.TabIndex = 1;
//
// FormMain
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(userTreeView);
Name = "FormMain";
Text = "Основная форма";
Load += FormMain_Load;
contextMenuStrip.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private ContextMenuStrip contextMenuStrip;
private ComponentsLibrary.VisualComponents.UserTreeView userTreeView;
private ToolStripMenuItem createElementToolStripMenuItem;
private ToolStripMenuItem updateElementToolStripMenuItem;
private ToolStripMenuItem deleteElementToolStripMenuItem;
private ToolStripMenuItem createWordDocumentToolStripMenuItem;
private ToolStripMenuItem createExcelDocumentToolStripMenuItem;
private ToolStripMenuItem createPdfDocumentToolStripMenuItem;
private ComponentsLibraryNet60.DocumentWithTable.ComponentDocumentWithTableMultiHeaderWord componentDocumentWithTableMultiHeaderWord1;
private Components.NonVisualComponents.BigTextComponent bigTextComponent1;
private ComponentsLibrary.NonVisualComponents.PdfPieChart pdfPieChart1;
private ToolStripMenuItem orderTypesToolStripMenuItem;
}
}

View File

@ -0,0 +1,433 @@
using ComponentsLibrary.NonVisualComponents.HelperModels;
using ComponentsLibraryNet60.Models;
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
using Contracts.ViewModels;
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 WinForms
{
/// <summary>
/// Главная форма
/// </summary>
public partial class FormMain : Form
{
/// <summary>
/// Бизнес-логика для сущности "Счет"
/// </summary>
private readonly IOrderLogic _orderLogic;
/// <summary>
/// Бизнес-логика для сущности "Тип заказа"
/// </summary>
private readonly IOrderTypeLogic _orderTypeLogic;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="orderLogic"></param>
/// <param name="orderTypeLogic"></param>
public FormMain(IOrderLogic orderLogic, IOrderTypeLogic orderTypeLogic)
{
InitializeComponent();
_orderLogic = orderLogic;
_orderTypeLogic = orderTypeLogic;
userTreeView.ContextMenuStrip = contextMenuStrip;
}
/// <summary>
/// Загрузка формы
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormMain_Load(object sender, EventArgs e)
{
var hierarchy = new List<string>()
{
"Type",
"Sum",
"Id",
"WaiterFullName"
};
userTreeView.SetHierarchy(hierarchy);
LoadData();
}
/// <summary>
/// Элемент контекстного меню "Добавить запись"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void createElementToolStripMenuItem_Click(object sender, EventArgs e)
{
AddElement();
}
/// <summary>
/// Элемент контекстного меню "Редактировать запись"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void updateElementToolStripMenuItem_Click(object sender, EventArgs e)
{
UpdateElement();
}
/// <summary>
/// Элемент контекстного меню "Удалить запись"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void deleteElementToolStripMenuItem_Click(object sender, EventArgs e)
{
DeleteElement();
}
/// <summary>
/// Элемент контекстного меню "Создать документ Word"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void createWordDocumentToolStripMenuItem_Click(object sender, EventArgs e)
{
CreateWordDocument();
}
/// <summary>
/// Элемент контекстного меню "Создать документ Excel"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void createExcelDocumentToolStripMenuItem_Click(object sender, EventArgs e)
{
CreateExcelDocument();
}
/// <summary>
/// Элемент контекстного меню "Создать документ Pdf"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void createPdfDocumentToolStripMenuItem_Click(object sender, EventArgs e)
{
CreatePdfDocument();
}
/// <summary>
/// Элемент контекстного меню "Типы заказов"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void orderTypesToolStripMenuItem_Click(object sender, EventArgs e)
{
ShowFormOrderTypes();
}
/// <summary>
/// Загрузка данных
/// </summary>
private void LoadData()
{
try
{
var orders = _orderLogic.ReadList(null);
if (orders == null)
{
return;
}
foreach (var order in orders)
{
if (string.IsNullOrEmpty(order.Sum))
{
order.Sum = "По акции";
}
userTreeView.AddObjectToTree(order);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Добавить запись
/// </summary>
private void AddElement()
{
var service = Program.ServiceProvider?.GetService(typeof(FormOrder));
if (!(service is FormOrder form))
{
return;
}
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
/// <summary>
/// Редактировать запись
/// </summary>
private void UpdateElement()
{
var service = Program.ServiceProvider?.GetService(typeof(FormOrder));
if (!(service is FormOrder form))
{
return;
}
var selectedOrder = userTreeView.GetSelectedObject<OrderViewModel>();
if (selectedOrder == null)
{
MessageBox.Show("Выберите счет для редактирования!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
form.Id = Convert.ToInt32(selectedOrder.Id);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
/// <summary>
/// Удалить запись
/// </summary>
private void DeleteElement()
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
{
return;
}
var selectedOrder = userTreeView.GetSelectedObject<OrderViewModel>();
int id = Convert.ToInt32(selectedOrder.Id);
try
{
_orderLogic.Delete(new OrderBindingModel { Id = id });
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
LoadData();
}
/// <summary>
/// Создать документ Word
/// </summary>
private void CreateWordDocument()
{
string fileName = "";
using (var dialog = new SaveFileDialog { Filter = "docx|*.docx" })
{
if (dialog.ShowDialog() == DialogResult.OK)
{
fileName = dialog.FileName.ToString();
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
var orders = _orderLogic.ReadList(null);
if (orders == null)
{
return;
}
foreach (var order in orders)
{
if (string.IsNullOrEmpty(order.Sum))
{
order.Sum = "По акции";
}
}
componentDocumentWithTableMultiHeaderWord1.CreateDoc(new ComponentDocumentWithTableHeaderDataConfig<OrderViewModel>
{
FilePath = fileName,
Header = "Информация по счетам.",
ColumnsRowsWidth = new List<(int Column, int Row)>()
{
(5, 5),
(10, 5),
(15, 0),
(15, 0),
},
Headers = new List<(int ColumnIndex, int RowIndex, string Header, string PropertyName)>()
{
(0, 0, "Id", "Id"),
(1, 0, "ФИО официанта", "WaiterFullName"),
(2, 0, "Тип заказа", "Type"),
(3, 0, "Сумма заказа", "Sum")
},
Data = orders,
});
}
/// <summary>
/// Создать документ Excel
/// </summary>
private void CreateExcelDocument()
{
string fileName = "";
using (var dialog = new SaveFileDialog { Filter = "xlsx|*.xlsx" })
{
if (dialog.ShowDialog() == DialogResult.OK)
{
fileName = dialog.FileName.ToString();
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
var orders = _orderLogic.ReadList(null);
if (orders == null)
{
return;
}
string title = "Информация по аукционным счетам.";
List<string> rows = new List<string>();
foreach (var order in orders)
{
if (string.IsNullOrEmpty(order.Sum))
{
string row = $"ФИО официанта: {order.WaiterFullName} -- Описание счета: {order.Info}";
rows.Add(row);
}
}
string[] rowsArray = rows.ToArray();
bigTextComponent1.CreateDocument(fileName, title, rowsArray);
}
/// <summary>
/// Создать документ Pdf
/// </summary>
private void CreatePdfDocument()
{
string fileName = "";
using (var dialog = new SaveFileDialog { Filter = "pdf|*.pdf" })
{
if (dialog.ShowDialog() == DialogResult.OK)
{
fileName = dialog.FileName.ToString();
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
var orders = _orderLogic.ReadList(null);
if (orders == null)
{
return;
}
var orderTypes = _orderTypeLogic.ReadList(null);
if (orderTypes == null)
{
return;
}
List<(double, string)> items = new List<(double, string)>();
foreach (var orderType in orderTypes)
{
int count = 0;
foreach (var order in orders)
{
if (order.Type == orderType.Name && string.IsNullOrEmpty(order.Sum))
{
count++;
}
}
items.Add((count, orderType.Name));
}
pdfPieChart1.CreatePieChart(new DataForPieChart(fileName, "Информация по оплаченным счетам каждого типа заказов", "Круговая диаграмма", DiagramLegendEnum.Top, "Типы заказов", items));
}
/// <summary>
/// Вывести форму списка типов заказов
/// </summary>
private void ShowFormOrderTypes()
{
var service = Program.ServiceProvider?.GetService(typeof(FormOrderTypes));
if (!(service is FormOrderTypes form))
{
return;
}
form.ShowDialog();
}
/// <summary>
/// Обработка нажатия кнопок
/// </summary>
/// <param name="msg"></param>
/// <param name="keyData"></param>
/// <returns></returns>
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
// Ctrl+A - добавить запись
if (keyData == (Keys.Control | Keys.A))
{
AddElement();
return true;
}
// Ctrl+U - редактировать запись
if (keyData == (Keys.Control | Keys.U))
{
UpdateElement();
return true;
}
// Ctrl+D - удалить запись
if (keyData == (Keys.Control | Keys.D))
{
DeleteElement();
return true;
}
// Ctrl+S - создать документ Word
if (keyData == (Keys.Control | Keys.S))
{
CreateWordDocument();
return true;
}
// Ctrl+T - создать документ Excel
if (keyData == (Keys.Control | Keys.T))
{
CreateExcelDocument();
return true;
}
// Ctrl+C - создать документ Pdf
if (keyData == (Keys.Control | Keys.C))
{
CreatePdfDocument();
return true;
}
// Ctrl+M - вывести форму списка типов заказов
if (keyData == (Keys.Control | Keys.M))
{
ShowFormOrderTypes();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
}

View File

@ -0,0 +1,132 @@
<?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="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="componentDocumentWithTableMultiHeaderWord1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>166, 17</value>
</metadata>
<metadata name="bigTextComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>491, 17</value>
</metadata>
<metadata name="pdfPieChart1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>653, 17</value>
</metadata>
</root>

View File

@ -0,0 +1,92 @@
namespace WinForms
{
partial class FormNonVisualComponents
{
/// <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();
buttonCreateTextDocument = new Button();
buttonCreateTableDocument = new Button();
buttonCreateDiagramDocument = new Button();
bigTextComponent1 = new Components.NonVisualComponents.BigTextComponent(components);
tableComponent1 = new Components.NonVisualComponents.TableComponent(components);
diagramComponent1 = new Components.NonVisualComponents.DiagramComponent(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 Components.NonVisualComponents.BigTextComponent bigTextComponent1;
private Components.NonVisualComponents.TableComponent tableComponent1;
private Components.NonVisualComponents.DiagramComponent diagramComponent1;
}
}

View File

@ -0,0 +1,124 @@
using Components.NonVisualComponents;
using Components.NonVisualComponents.HelperModels;
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 WinForms.DataModels;
namespace WinForms
{
/// <summary>
/// Форма для не визуальных компонентов
/// </summary>
public partial class FormNonVisualComponents : Form
{
/// <summary>
/// Конструктор
/// </summary>
public FormNonVisualComponents()
{
InitializeComponent();
}
/// <summary>
/// Создать документ с текстом
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCreateTextDocument_Click(object sender, EventArgs e)
{
string filepath = "C:\\Users\\masen\\OneDrive\\Рабочий стол\\BigTextDocumentExcel.xlsx";
string title = "Документ с большим текстом";
string[] rows =
{
"Съешь еще",
"этих мягких",
"французских булок",
"да выпей чаю"
};
bigTextComponent1.CreateDocument(filepath, title, rows);
}
/// <summary>
/// Создать документ с таблицей
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCreateTableDocument_Click(object sender, EventArgs e)
{
string filepath = "C:\\Users\\masen\\OneDrive\\Рабочий стол\\TableDocumentExcel.xlsx";
string title = "Документ с таблицей";
List<MergeCells> mergeCells = new List<MergeCells>()
{
new MergeCells("Личные данные", new int[] { 2, 3, 4 }),
new MergeCells("Работа", new int[] { 7, 8 })
};
List<ColumnInfo> columns = new List<ColumnInfo>()
{
new ColumnInfo("Id", "Идент.", 10),
new ColumnInfo("Status", "Статус", 10),
new ColumnInfo("Name", "Имя", 20),
new ColumnInfo("Surname", "Фамилия", 20),
new ColumnInfo("Age", "Возраст", 20),
new ColumnInfo("Kids", "Дети", 20),
new ColumnInfo("Car", "Машина", 20),
new ColumnInfo("Department", "Подразделение", 30),
new ColumnInfo("Post", "Должность", 30),
new ColumnInfo("Prize", "Премия", 10)
};
List<Employee> data = new List<Employee>()
{
new Employee(1, "нет", "Иван", "Иванов", 34, "нет", "есть", "Департамент 1", "Инженер", 2000.1),
new Employee(2, "нет", "Петр", "Петров", 44, "есть", "есть", "Департамент 1", "Инженер", 2000.1),
new Employee(3, "да", "Сергей", "Сепгеев", 55, "нет", "есть", "Департамент 1", "Руководитель", 5000.5),
new Employee(4, "нет", "Ольга", "Иванва", 34, "есть", "нет", "Бухгалтерия", "Бухгалтер", 2000.1),
new Employee(5, "да", "Татьяна", "Петрова", 44, "нет", "нет", "Бухгалтерия", "Старший бухгалтер", 7000.6)
};
tableComponent1.CreateDocument(filepath, title,
mergeCells, columns,
data);
}
/// <summary>
/// Создать документ с диаграммой
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCreateDiagramDocument_Click(object sender, EventArgs e)
{
LineChartConfig config = new LineChartConfig();
config.Filepath = "C:\\Users\\masen\\OneDrive\\Рабочий стол\\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,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="bigTextComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="tableComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>179, 17</value>
</metadata>
<metadata name="diagramComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>329, 17</value>
</metadata>
</root>

155
Components/WinForms/FormOrder.Designer.cs generated Normal file
View File

@ -0,0 +1,155 @@
namespace WinForms
{
partial class FormOrder
{
/// <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()
{
textBoxWaiterFullName = new TextBox();
buttonSave = new Button();
buttonCancel = new Button();
textBoxInfo = new TextBox();
customComboBox = new Components.VisualComponents.CustomComboBox();
controlInputNullableDouble = new ControlsLibraryNet60.Input.ControlInputNullableDouble();
label1 = new Label();
labelInfo = new Label();
labelSum = new Label();
SuspendLayout();
//
// textBoxWaiterFullName
//
textBoxWaiterFullName.Location = new Point(65, 60);
textBoxWaiterFullName.Name = "textBoxWaiterFullName";
textBoxWaiterFullName.Size = new Size(250, 23);
textBoxWaiterFullName.TabIndex = 0;
//
// buttonSave
//
buttonSave.Location = new Point(65, 320);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(75, 23);
buttonSave.TabIndex = 1;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(240, 320);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(75, 23);
buttonCancel.TabIndex = 2;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// textBoxInfo
//
textBoxInfo.Location = new Point(66, 120);
textBoxInfo.Name = "textBoxInfo";
textBoxInfo.Size = new Size(250, 23);
textBoxInfo.TabIndex = 3;
//
// customComboBox
//
customComboBox.Location = new Point(65, 150);
customComboBox.Name = "customComboBox";
customComboBox.SelectedItem = "";
customComboBox.Size = new Size(250, 53);
customComboBox.TabIndex = 4;
//
// controlInputNullableDouble
//
controlInputNullableDouble.BackColor = SystemColors.Window;
controlInputNullableDouble.BorderStyle = BorderStyle.Fixed3D;
controlInputNullableDouble.Location = new Point(66, 240);
controlInputNullableDouble.Margin = new Padding(5, 3, 5, 3);
controlInputNullableDouble.Name = "controlInputNullableDouble";
controlInputNullableDouble.Size = new Size(250, 23);
controlInputNullableDouble.TabIndex = 5;
controlInputNullableDouble.Value = null;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(66, 42);
label1.Name = "label1";
label1.Size = new Size(103, 15);
label1.TabIndex = 6;
label1.Text = "ФИО официанта*";
//
// labelInfo
//
labelInfo.AutoSize = true;
labelInfo.Location = new Point(66, 102);
labelInfo.Name = "labelInfo";
labelInfo.Size = new Size(136, 15);
labelInfo.TabIndex = 7;
labelInfo.Text = "Информация по счету*";
//
// labelSum
//
labelSum.AutoSize = true;
labelSum.Location = new Point(66, 222);
labelSum.Name = "labelSum";
labelSum.Size = new Size(45, 15);
labelSum.TabIndex = 8;
labelSum.Text = "Сумма";
//
// FormOrder
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(384, 361);
Controls.Add(labelSum);
Controls.Add(labelInfo);
Controls.Add(label1);
Controls.Add(controlInputNullableDouble);
Controls.Add(customComboBox);
Controls.Add(textBoxInfo);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(textBoxWaiterFullName);
Name = "FormOrder";
Text = "Счет";
Load += FormOrder_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBoxWaiterFullName;
private Button buttonSave;
private Button buttonCancel;
private TextBox textBoxInfo;
private Components.VisualComponents.CustomComboBox customComboBox;
private ControlsLibraryNet60.Input.ControlInputNullableDouble controlInputNullableDouble;
private Label label1;
private Label labelInfo;
private Label labelSum;
}
}

View File

@ -0,0 +1,159 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
using Contracts.SearchModels;
using DocumentFormat.OpenXml.Office2010.Excel;
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 WinForms
{
/// <summary>
/// Форма для создания или редактирования счета
/// </summary>
public partial class FormOrder : Form
{
/// <summary>
/// Бизнес-логика для сущности "Счет"
/// </summary>
private readonly IOrderLogic _orderLogic;
/// <summary>
/// Бизнес-логика для сущности "Тип заказа"
/// </summary>
private readonly IOrderTypeLogic _orderTypeLogic;
/// <summary>
/// Идентификатор счета
/// </summary>
private int? _id;
/// <summary>
/// Идентификатор счета
/// </summary>
public int Id { set { _id = value; } }
/// <summary>
/// Конструктор
/// </summary>
/// <param name="orderLogic"></param>
/// <param name="orderTypeLogic"></param>
public FormOrder(IOrderLogic orderLogic, IOrderTypeLogic orderTypeLogic)
{
InitializeComponent();
_orderLogic = orderLogic;
_orderTypeLogic = orderTypeLogic;
}
/// <summary>
/// Загрузка формы
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormOrder_Load(object sender, EventArgs e)
{
var listOrderTypes = _orderTypeLogic.ReadList(null);
if (listOrderTypes != null)
{
foreach (var type in listOrderTypes)
{
customComboBox.AddItem(type.Name);
}
}
if (!_id.HasValue)
{
return;
}
try
{
var order = _orderLogic.ReadElement(new OrderSearchModel { Id = _id.Value });
if (order == null)
{
return;
}
textBoxWaiterFullName.Text = order.WaiterFullName;
textBoxInfo.Text = order.Info;
customComboBox.SelectedItem = order.Type;
if (!string.IsNullOrEmpty(order.Sum))
{
controlInputNullableDouble.Value = double.Parse(order.Sum!);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Кнопка "Сохранить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxWaiterFullName.Text))
{
MessageBox.Show("Заполните ФИО официанта!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxInfo.Text))
{
MessageBox.Show("Заполните информацию по счету!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(customComboBox.SelectedItem))
{
MessageBox.Show("Выберите тип заказа!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
var model = new OrderBindingModel
{
Id = _id ?? 0,
WaiterFullName = textBoxWaiterFullName.Text,
Info = textBoxInfo.Text,
Type = customComboBox.SelectedItem,
Sum = controlInputNullableDouble.Value,
};
var operatingResult = _id.HasValue ? _orderLogic.Update(model) : _orderLogic.Create(model);
if (!operatingResult)
{
throw new Exception("Ошибка при создании сущности 'Счет'!");
}
MessageBox.Show("Создание сущности 'Счет' прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Кнопка "Отмена"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

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,66 @@
namespace WinForms
{
partial class FormOrderTypes
{
/// <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()
{
dataGridView = new DataGridView();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.BackgroundColor = SystemColors.Control;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Fill;
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.RowTemplate.Height = 25;
dataGridView.Size = new Size(384, 211);
dataGridView.TabIndex = 0;
dataGridView.CellEndEdit += dataGridView_CellEndEdit;
dataGridView.KeyDown += dataGridView_KeyDown;
//
// FormOrderTypes
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(384, 211);
Controls.Add(dataGridView);
Name = "FormOrderTypes";
Text = "Типы заказов";
Load += FormOrderTypes_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
}
}

View File

@ -0,0 +1,160 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
using DocumentFormat.OpenXml.Office2010.ExcelAc;
using Microsoft.Extensions.Logging;
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 WinForms
{
/// <summary>
/// Форма для типов заказов
/// </summary>
public partial class FormOrderTypes : Form
{
/// <summary>
/// Бизнес-логика для сущности "Тип заказа"
/// </summary>
private readonly IOrderTypeLogic _orderTypeLogic;
/// <summary>
/// Список типов заказов
/// </summary>
private BindingList<OrderTypeBindingModel> _bindingList;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="orderTypeLogic"></param>
public FormOrderTypes(IOrderTypeLogic orderTypeLogic)
{
InitializeComponent();
_orderTypeLogic = orderTypeLogic;
_bindingList = new BindingList<OrderTypeBindingModel>();
}
/// <summary>
/// Загрузка формы
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormOrderTypes_Load(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Создание или редактирование типа заказа
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="Exception"></exception>
private void dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
var typeName = dataGridView.CurrentRow.Cells[1].Value.ToString();
if (!string.IsNullOrEmpty(typeName))
{
int id = dataGridView.CurrentRow.Cells[0].Value != null
? Convert.ToInt32(dataGridView.CurrentRow.Cells[0].Value)
: 0;
string name = dataGridView.CurrentRow.Cells[1].EditedFormattedValue.ToString()!;
var model = new OrderTypeBindingModel
{
Id = id,
Name = name
};
var operatingResult = id != 0 ? _orderTypeLogic.Update(model) : _orderTypeLogic.Create(model);
if (!operatingResult)
{
throw new Exception("Ошибка при создании сущности 'Тип заказа'!");
}
}
else
{
MessageBox.Show("Введена пустая строка!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
LoadData();
}
/// <summary>
/// Обработка нажатия кнопок
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void dataGridView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Insert)
{
if (dataGridView.Rows.Count == 0)
{
_bindingList.Add(new OrderTypeBindingModel());
dataGridView.DataSource = new BindingList<OrderTypeBindingModel>(_bindingList);
dataGridView.CurrentCell = dataGridView.Rows[0].Cells[1];
return;
}
if (dataGridView.Rows[dataGridView.Rows.Count - 1].Cells[1].Value != null)
{
_bindingList.Add(new OrderTypeBindingModel());
dataGridView.DataSource = new BindingList<OrderTypeBindingModel>(_bindingList);
dataGridView.CurrentCell = dataGridView.Rows[dataGridView.Rows.Count - 1].Cells[1];
return;
}
}
if (e.KeyData == Keys.Delete)
{
if (MessageBox.Show("Удалить выбранный элемент?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
_orderTypeLogic.Delete(new OrderTypeBindingModel { Id = (int)dataGridView.CurrentRow.Cells[0].Value });
LoadData();
}
}
}
/// <summary>
/// Загрузка данных
/// </summary>
private void LoadData()
{
try
{
var types = _orderTypeLogic.ReadList(null);
if (types == null)
{
return;
}
_bindingList.Clear();
foreach (var type in types)
{
_bindingList.Add(new OrderTypeBindingModel
{
Id = type.Id,
Name = type.Name,
});
}
if (_bindingList != null)
{
dataGridView.DataSource = _bindingList;
dataGridView.Columns[0].Visible = false;
dataGridView.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

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,272 @@
namespace WinForms
{
partial class FormVisualComponents
{
/// <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()
{
groupBox1 = new GroupBox();
labelItem = new Label();
buttonGetItem = new Button();
buttonClearItems = new Button();
buttonAddItems = new Button();
customComboBox = new Components.VisualComponents.CustomComboBox();
groupBox2 = new GroupBox();
buttonSetDateExample = new Button();
textBoxDateExample = new TextBox();
checkBoxValidate = new CheckBox();
buttonValidate = new Button();
customTextBox = new Components.VisualComponents.CustomTextBox();
groupBox3 = new GroupBox();
labelObjectInfo = new Label();
buttonGetObject = new Button();
buttonAddObjects = new Button();
customListBox = new Components.VisualComponents.CustomListBox();
groupBox1.SuspendLayout();
groupBox2.SuspendLayout();
groupBox3.SuspendLayout();
SuspendLayout();
//
// groupBox1
//
groupBox1.Controls.Add(labelItem);
groupBox1.Controls.Add(buttonGetItem);
groupBox1.Controls.Add(buttonClearItems);
groupBox1.Controls.Add(buttonAddItems);
groupBox1.Controls.Add(customComboBox);
groupBox1.Dock = DockStyle.Left;
groupBox1.Location = new Point(0, 0);
groupBox1.Name = "groupBox1";
groupBox1.Size = new Size(275, 461);
groupBox1.TabIndex = 0;
groupBox1.TabStop = false;
groupBox1.Text = "Тест для ComboBox";
//
// labelItem
//
labelItem.AutoSize = true;
labelItem.BorderStyle = BorderStyle.Fixed3D;
labelItem.Font = new Font("Segoe UI", 11F, FontStyle.Regular, GraphicsUnit.Point);
labelItem.Location = new Point(143, 140);
labelItem.Name = "labelItem";
labelItem.Size = new Size(70, 22);
labelItem.TabIndex = 4;
labelItem.Text = "Элемент";
//
// buttonGetItem
//
buttonGetItem.Location = new Point(12, 139);
buttonGetItem.Name = "buttonGetItem";
buttonGetItem.Size = new Size(125, 23);
buttonGetItem.TabIndex = 3;
buttonGetItem.Text = "Получить элемент";
buttonGetItem.UseVisualStyleBackColor = true;
buttonGetItem.Click += buttonGetItem_Click;
//
// buttonClearItems
//
buttonClearItems.Location = new Point(12, 110);
buttonClearItems.Name = "buttonClearItems";
buttonClearItems.Size = new Size(125, 23);
buttonClearItems.TabIndex = 2;
buttonClearItems.Text = "Очистить элементы";
buttonClearItems.UseVisualStyleBackColor = true;
buttonClearItems.Click += buttonClearItems_Click;
//
// buttonAddItems
//
buttonAddItems.Location = new Point(12, 81);
buttonAddItems.Name = "buttonAddItems";
buttonAddItems.Size = new Size(125, 23);
buttonAddItems.TabIndex = 1;
buttonAddItems.Text = "Добавить элементы";
buttonAddItems.UseVisualStyleBackColor = true;
buttonAddItems.Click += buttonAddItems_Click;
//
// customComboBox
//
customComboBox.Location = new Point(12, 22);
customComboBox.Name = "customComboBox";
customComboBox.SelectedItem = "";
customComboBox.Size = new Size(257, 53);
customComboBox.TabIndex = 0;
//
// groupBox2
//
groupBox2.Controls.Add(buttonSetDateExample);
groupBox2.Controls.Add(textBoxDateExample);
groupBox2.Controls.Add(checkBoxValidate);
groupBox2.Controls.Add(buttonValidate);
groupBox2.Controls.Add(customTextBox);
groupBox2.Dock = DockStyle.Left;
groupBox2.Location = new Point(275, 0);
groupBox2.Name = "groupBox2";
groupBox2.Size = new Size(253, 461);
groupBox2.TabIndex = 1;
groupBox2.TabStop = false;
groupBox2.Text = "Тест для TextBox";
//
// buttonSetDateExample
//
buttonSetDateExample.Location = new Point(64, 168);
buttonSetDateExample.Name = "buttonSetDateExample";
buttonSetDateExample.Size = new Size(125, 23);
buttonSetDateExample.TabIndex = 4;
buttonSetDateExample.Text = "Изменить пример";
buttonSetDateExample.UseVisualStyleBackColor = true;
buttonSetDateExample.Click += buttonSetDateExample_Click;
//
// textBoxDateExample
//
textBoxDateExample.Location = new Point(6, 139);
textBoxDateExample.Name = "textBoxDateExample";
textBoxDateExample.PlaceholderText = "01.01.1970";
textBoxDateExample.Size = new Size(241, 23);
textBoxDateExample.TabIndex = 3;
//
// checkBoxValidate
//
checkBoxValidate.AutoSize = true;
checkBoxValidate.Enabled = false;
checkBoxValidate.Location = new Point(167, 84);
checkBoxValidate.Name = "checkBoxValidate";
checkBoxValidate.RightToLeft = RightToLeft.No;
checkBoxValidate.Size = new Size(80, 19);
checkBoxValidate.TabIndex = 2;
checkBoxValidate.Text = "Проверка";
checkBoxValidate.UseVisualStyleBackColor = true;
//
// buttonValidate
//
buttonValidate.Location = new Point(6, 81);
buttonValidate.Name = "buttonValidate";
buttonValidate.Size = new Size(75, 23);
buttonValidate.TabIndex = 1;
buttonValidate.Text = "Проверка";
buttonValidate.UseVisualStyleBackColor = true;
buttonValidate.Click += buttonValidate_Click;
//
// customTextBox
//
customTextBox.DatePattern = null;
customTextBox.Location = new Point(6, 22);
customTextBox.Name = "customTextBox";
customTextBox.Size = new Size(241, 53);
customTextBox.TabIndex = 0;
//
// groupBox3
//
groupBox3.Controls.Add(labelObjectInfo);
groupBox3.Controls.Add(buttonGetObject);
groupBox3.Controls.Add(buttonAddObjects);
groupBox3.Controls.Add(customListBox);
groupBox3.Dock = DockStyle.Right;
groupBox3.Location = new Point(534, 0);
groupBox3.Name = "groupBox3";
groupBox3.Size = new Size(350, 461);
groupBox3.TabIndex = 2;
groupBox3.TabStop = false;
groupBox3.Text = "Тест для ListBox";
//
// labelObjectInfo
//
labelObjectInfo.AutoSize = true;
labelObjectInfo.BorderStyle = BorderStyle.Fixed3D;
labelObjectInfo.Font = new Font("Segoe UI", 11F, FontStyle.Regular, GraphicsUnit.Point);
labelObjectInfo.Location = new Point(132, 426);
labelObjectInfo.Name = "labelObjectInfo";
labelObjectInfo.Size = new Size(190, 22);
labelObjectInfo.TabIndex = 3;
labelObjectInfo.Text = " Информация об объекте";
//
// buttonGetObject
//
buttonGetObject.Location = new Point(6, 426);
buttonGetObject.Name = "buttonGetObject";
buttonGetObject.Size = new Size(120, 23);
buttonGetObject.TabIndex = 2;
buttonGetObject.Text = "Получить объект";
buttonGetObject.UseVisualStyleBackColor = true;
buttonGetObject.Click += buttonGetObject_Click;
//
// buttonAddObjects
//
buttonAddObjects.Location = new Point(6, 397);
buttonAddObjects.Name = "buttonAddObjects";
buttonAddObjects.Size = new Size(120, 23);
buttonAddObjects.TabIndex = 1;
buttonAddObjects.Text = "Добавить объекты";
buttonAddObjects.UseVisualStyleBackColor = true;
buttonAddObjects.Click += buttonAddObjects_Click;
//
// customListBox
//
customListBox.Location = new Point(6, 22);
customListBox.Name = "customListBox";
customListBox.SelectedIndex = -1;
customListBox.Size = new Size(332, 369);
customListBox.TabIndex = 0;
//
// FormVisualComponents
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(884, 461);
Controls.Add(groupBox3);
Controls.Add(groupBox2);
Controls.Add(groupBox1);
Name = "FormVisualComponents";
Text = "Визуальные компоненты";
groupBox1.ResumeLayout(false);
groupBox1.PerformLayout();
groupBox2.ResumeLayout(false);
groupBox2.PerformLayout();
groupBox3.ResumeLayout(false);
groupBox3.PerformLayout();
ResumeLayout(false);
}
#endregion
private GroupBox groupBox1;
private GroupBox groupBox2;
private GroupBox groupBox3;
private Button buttonAddObjects;
private Components.VisualComponents.CustomListBox customListBox;
private Label labelObjectInfo;
private Button buttonGetObject;
private Button buttonAddItems;
private Components.VisualComponents.CustomComboBox customComboBox;
private Button buttonGetItem;
private Button buttonClearItems;
private Label labelItem;
private CheckBox checkBoxValidate;
private Button buttonValidate;
private Components.VisualComponents.CustomTextBox customTextBox;
private Button buttonSetDateExample;
private TextBox textBoxDateExample;
}
}

View File

@ -0,0 +1,141 @@
using Components.VisualComponents.HelperModels;
using WinForms.DataModels;
namespace WinForms
{
/// <summary>
/// Ôîðìà äëÿ âèçóàëüíûõ êîìïîíåíòîâ
/// </summary>
public partial class FormVisualComponents : Form
{
/// <summary>
/// Êîíñòðóêòîð
/// </summary>
public FormVisualComponents()
{
InitializeComponent();
customComboBox.AddItem("Ýëåìåíò 1");
customComboBox.AddItem("Ýëåìåíò 2");
customComboBox.AddItem("Ýëåìåíò 3");
customTextBox.DatePattern = @"^(\d{2}.\d{2}.\d{4})$";
CustomListBoxConfig config = new();
config.LayoutString = "Èìÿ {Name} Ôàìèëèÿ {Surname}";
config.StartSymbol = "{";
config.EndSymbol = "}";
customListBox.SetConfig(config);
}
/// <summary>
/// Äîáàâèòü ýäåìåíòû â customComboBox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonAddItems_Click(object sender, EventArgs e)
{
customComboBox.AddItem("Ýëåìåíò 3");
customComboBox.AddItem("Ýëåìåíò 4");
customComboBox.AddItem("Ýëåìåíò 5");
}
/// <summary>
/// Î÷èñòèòü ñïèñîê ýëåìåíòîâ customComboBox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonClearItems_Click(object sender, EventArgs e)
{
customComboBox.Clear();
}
/// <summary>
/// Ïîëó÷èòü âûáðàííûé ýëåìåíò èç customComboBox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonGetItem_Click(object sender, EventArgs e)
{
labelItem.Text = customComboBox.SelectedItem.ToString();
}
/// <summary>
/// Ïðîâåðêà ââåäåííîãî çíà÷åíèÿ ñ çàäàííûì øàáëîíîì customTextBox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonValidate_Click(object sender, EventArgs e)
{
try
{
if (customTextBox.TextBoxValue != null)
{
checkBoxValidate.Text = "Ïîäõîäèò";
checkBoxValidate.Checked = true;
checkBoxValidate.BackColor = Color.LightGreen;
}
}
catch (Exception ex)
{
checkBoxValidate.Text = "Íå ïîäõîäèò";
checkBoxValidate.Checked = false;
checkBoxValidate.BackColor = Color.Red;
MessageBox.Show(ex.Message);
}
}
/// <summary>
/// Èçìåíèòü ïðèìåð çàäàííîãî øàáëîíà customTextBox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSetDateExample_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxDateExample.Text))
{
return;
}
if (customTextBox.SetDateExample(textBoxDateExample.Text))
{
MessageBox.Show("Ïðèìåð çàäàííîãî øàáëîíà óñïåøíî èçìåí¸í!", "Óñïåõ", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Ïðèìåð çàäàííîãî øàáëîíà íå ïîäõîäèò!", "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Äîáàâèòü îáúåêòû â customListBox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonAddObjects_Click(object sender, EventArgs e)
{
customListBox.AddObject<Person>(new Person("Åâãåíèé", "Ýãîâ"));
customListBox.AddObject<Person>(new Person("Àíòîí", "Ñêàëêèí"));
customListBox.AddObject<Person>(new Person("Ìàêñèì", "Ìàñåíüêèí"));
}
/// <summary>
/// Ïîëó÷èòü îáúåêò èç customListBox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonGetObject_Click(object sender, EventArgs e)
{
Employee person = customListBox.GetObject<Employee>();
if (person == null)
{
labelObjectInfo.Text = "Îáúåêò íå íàéäåí";
return;
}
string objectInfo = person.Name + " " + person.Surname;
labelObjectInfo.Text = objectInfo;
}
}
}

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,335 @@
using BusinessLogics.BusinessLogics;
using Components.NonVisualComponents;
using ComponentsLibrary.NonVisualComponents.HelperModels;
using ComponentsLibrary.NonVisualComponents;
using ComponentsLibrary.VisualComponents;
using ComponentsLibraryNet60.DocumentWithTable;
using ComponentsLibraryNet60.Models;
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
using Contracts.ViewModels;
using DatabaseImplement.Implements;
using Microsoft.Extensions.Logging;
using Plugins;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NLog.Extensions.Logging;
namespace WinForms
{
/// <summary>
/// Реализация интерфейса-соглашения для плагинов
/// </summary>
public class PluginsConvention : IPluginsConvention
{
/// <summary>
/// Название плагина
/// </summary>
public string PluginName => "Orders";
/// <summary>
/// Визуальный компонент для вывода списка в виде дерева
/// </summary>
private readonly UserTreeView _userTreeView;
/// <summary>
/// Бизнес-логика для сущности "Счет"
/// </summary>
private readonly IOrderLogic _orderLogic;
/// <summary>
/// Бизнес-логика для сущности "Тип заказа"
/// </summary>
private readonly IOrderTypeLogic _orderTypeLogic;
/// <summary>
/// Конструктор
/// </summary>
public PluginsConvention()
{
_userTreeView = new UserTreeView();
var hierarchy = new List<string>()
{
"Type",
"Sum",
"Id",
"WaiterFullName"
};
_userTreeView.SetHierarchy(hierarchy);
var loggerFactory = LoggerFactory.Create(builder => builder.AddNLog());
var orderLogicLogger = loggerFactory.CreateLogger<OrderLogic>();
var orderTypeLogicLogger = loggerFactory.CreateLogger<OrderTypeLogic>();
_orderLogic = new OrderLogic(orderLogicLogger, new OrderStorage());
_orderTypeLogic = new OrderTypeLogic(orderTypeLogicLogger, new OrderTypeStorage());
}
/// <summary>
/// Получение контрола для вывода набора данных
/// </summary>
public UserControl GetControl
{
get
{
ReloadData();
return _userTreeView;
}
}
/// <summary>
/// Получение элемента, выбранного в контроле
/// </summary>
public PluginsConventionElement GetElement
{
get
{
var order = _userTreeView.GetSelectedObject<OrderViewModel>();
int id = -1;
if (order != null)
{
id = order.Id;
}
byte[] bytes = new byte[16];
BitConverter.GetBytes(id).CopyTo(bytes, 0);
return new PluginsConventionElement { Id = new Guid(bytes) };
}
}
/// <summary>
/// Получение формы для создания/редактирования объекта
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
public Form GetForm(PluginsConventionElement element)
{
if (element == null)
{
return new FormOrder(_orderLogic, _orderTypeLogic);
}
if (element.Id.GetHashCode() >= 0)
{
byte[] bytes = element.Id.ToByteArray();
int Id = BitConverter.ToInt32(bytes, 0);
var form = new FormOrder(_orderLogic, _orderTypeLogic);
form.Id = Id;
return form;
}
return null;
}
/// <summary>
/// Получение формы для работы со справочником
/// </summary>
/// <returns></returns>
public Form GetThesaurus()
{
return new FormOrderTypes(_orderTypeLogic);
}
/// <summary>
/// Удаление элемента
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
public bool DeleteElement(PluginsConventionElement element)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
{
return false;
}
byte[] bytes = element.Id.ToByteArray();
int Id = BitConverter.ToInt32(bytes, 0);
try
{
_orderLogic.Delete(new OrderBindingModel() { Id = Id });
ReloadData();
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
/// <summary>
/// Обновление набора данных в контроле
/// </summary>
public void ReloadData()
{
try
{
var orders = _orderLogic.ReadList(null);
if (orders == null)
{
return;
}
foreach (var order in orders)
{
if (string.IsNullOrEmpty(order.Sum))
{
order.Sum = "По акции";
}
_userTreeView.AddObjectToTree(order);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Создание простого документа
/// </summary>
/// <param name="saveDocument"></param>
/// <returns></returns>
public bool CreateSimpleDocument(PluginsConventionSaveDocument saveDocument)
{
try
{
var orders = _orderLogic.ReadList(null);
if (orders == null)
{
return false;
}
string title = "Информация по аукционным счетам.";
List<string> rows = new List<string>();
foreach (var order in orders)
{
if (string.IsNullOrEmpty(order.Sum))
{
string row = $"ФИО официанта: {order.WaiterFullName} -- Описание счета: {order.Info}";
rows.Add(row);
}
}
string[] rowsArray = rows.ToArray();
var bigTextComponent = new BigTextComponent();
bigTextComponent.CreateDocument(saveDocument.FileName, title, rowsArray);
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
/// <summary>
/// Создание документа с настраиваемой таблицей
/// </summary>
/// <param name="saveDocument"></param>
/// <returns></returns>
public bool CreateTableDocument(PluginsConventionSaveDocument saveDocument)
{
try
{
var orders = _orderLogic.ReadList(null);
if (orders == null)
{
return false;
}
foreach (var order in orders)
{
if (string.IsNullOrEmpty(order.Sum))
{
order.Sum = "По акции";
}
}
var componentDocumentWithTableMultiHeaderWord = new ComponentDocumentWithTableMultiHeaderWord();
componentDocumentWithTableMultiHeaderWord.CreateDoc(new ComponentDocumentWithTableHeaderDataConfig<OrderViewModel>
{
FilePath = saveDocument.FileName,
Header = "Информация по счетам.",
ColumnsRowsWidth = new List<(int Column, int Row)>()
{
(5, 5),
(10, 5),
(15, 0),
(15, 0),
},
Headers = new List<(int ColumnIndex, int RowIndex, string Header, string PropertyName)>()
{
(0, 0, "Id", "Id"),
(1, 0, "ФИО официанта", "WaiterFullName"),
(2, 0, "Тип заказа", "Type"),
(3, 0, "Сумма заказа", "Sum")
},
Data = orders,
});
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
/// <summary>
/// Создание документа с диаграммой
/// </summary>
/// <param name="saveDocument"></param>
/// <returns></returns>
public bool CreateChartDocument(PluginsConventionSaveDocument saveDocument)
{
try
{
var orders = _orderLogic.ReadList(null);
if (orders == null)
{
return false;
}
var orderTypes = _orderTypeLogic.ReadList(null);
if (orderTypes == null)
{
return false;
}
List<(double, string)> items = new List<(double, string)>();
foreach (var orderType in orderTypes)
{
int count = 0;
foreach (var order in orders)
{
if (order.Type == orderType.Name && string.IsNullOrEmpty(order.Sum))
{
count++;
}
}
items.Add((count, orderType.Name));
}
var pdfPieChart = new PdfPieChart();
pdfPieChart.CreatePieChart(new DataForPieChart(saveDocument.FileName, "Информация по оплаченным счетам каждого типа заказов", "Круговая диаграмма", DiagramLegendEnum.Top, "Типы заказов", items));
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
}
}

View File

@ -1,7 +1,27 @@
using BusinessLogics.BusinessLogics;
using Contracts.BusinessLogicsContracts;
using Contracts.StoragesContracts;
using DatabaseImplement.Implements;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using Plugins;
using System;
namespace WinForms
{
internal static class Program
{
/// <summary>
/// IoC-êîíòåéíåð
/// </summary>
private static ServiceProvider? _serviceProvider;
/// <summary>
/// IoC-êîíòåéíåð
/// </summary>
public static ServiceProvider? ServiceProvider => _serviceProvider;
/// <summary>
/// The main entry point for the application.
/// </summary>
@ -11,7 +31,41 @@ namespace WinForms
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new FormComponents());
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
}
/// <summary>
/// Êîíôèãóðàöèÿ ñåðâèñîâ
/// </summary>
/// <param name="services"></param>
private static void ConfigureServices(ServiceCollection services)
{
// Ëîããåð
services.AddLogging(option =>
{
option.SetMinimumLevel(LogLevel.Information);
option.AddNLog("nlog.config");
});
// IoC-êîíòåéíåð, õðàíèëèùà
services.AddTransient<IOrderStorage, OrderStorage>();
services.AddTransient<IOrderTypeStorage, OrderTypeStorage>();
// IoC-êîíòåéíåð, áèçíåñ-ëîãèêà
services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<IOrderTypeLogic, OrderTypeLogic>();
// IoC-êîíòåéíåð, ôîðìû îòîáðàæåíèÿ
services.AddTransient<FormVisualComponents>();
services.AddTransient<FormNonVisualComponents>();
services.AddTransient<FormMain>();
services.AddTransient<FormOrder>();
services.AddTransient<FormOrderTypes>();
}
}
}

View File

@ -8,4 +8,38 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<None Remove="nlog.config" />
</ItemGroup>
<ItemGroup>
<Content Include="nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="ComponentsLibrary" Version="1.0.0" />
<PackageReference Include="ComponentsLibraryNet60" Version="1.0.0" />
<PackageReference Include="ControlsLibraryNet60" Version="1.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.13">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.13" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BusinessLogics\BusinessLogics.csproj" />
<ProjectReference Include="..\Components\Components.csproj" />
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\Plugins\Plugins.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="packages\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true" internalLogLevel="Info">
<targets>
<target xsi:type="File" name="tofile" fileName="log-${shortdate}.log" />
</targets>
<rules>
<logger name="*" minLevel="Debug" writeTo="tofile" />
</rules>
</nlog>
</configuration>

View File

@ -0,0 +1,184 @@
namespace WinFormsPlugins
{
partial class FormMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.ControlsStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ActionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.DocsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SimpleDocToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.TableDocToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ChartDocToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.panelControl = new System.Windows.Forms.Panel();
this.ThesaurusToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.AddElementToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.UpdElementToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.DelElementToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuStrip.SuspendLayout();
this.SuspendLayout();
//
// menuStrip
//
this.menuStrip.Items.AddRange(new
System.Windows.Forms.ToolStripItem[] {
this.ControlsStripMenuItem,
this.ActionsToolStripMenuItem,
this.DocsToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Size = new System.Drawing.Size(800, 24);
this.menuStrip.TabIndex = 0;
this.menuStrip.Text = "Меню";
//
// ControlsStripMenuItem
//
this.ControlsStripMenuItem.Name = "ControlsStripMenuItem";
this.ControlsStripMenuItem.Size = new System.Drawing.Size(94, 20);
this.ControlsStripMenuItem.Text = "Компоненты";
//
// ActionsToolStripMenuItem
//
this.ActionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.ThesaurusToolStripMenuItem,
this.AddElementToolStripMenuItem,
this.UpdElementToolStripMenuItem,
this.DelElementToolStripMenuItem});
this.ActionsToolStripMenuItem.Name = "ActionsToolStripMenuItem";
this.ActionsToolStripMenuItem.Size = new System.Drawing.Size(70, 20);
this.ActionsToolStripMenuItem.Text = "Действия";
//
// DocsToolStripMenuItem
//
this.DocsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.SimpleDocToolStripMenuItem,
this.TableDocToolStripMenuItem,
this.ChartDocToolStripMenuItem});
this.DocsToolStripMenuItem.Name = "DocsToolStripMenuItem";
this.DocsToolStripMenuItem.Size = new System.Drawing.Size(82, 20);
this.DocsToolStripMenuItem.Text = "Документы";
//
// SimpleDocToolStripMenuItem
//
this.SimpleDocToolStripMenuItem.Name = "SimpleDocToolStripMenuItem";
this.SimpleDocToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
this.SimpleDocToolStripMenuItem.Size = new System.Drawing.Size(233, 22);
this.SimpleDocToolStripMenuItem.Text = "Простой документ";
this.SimpleDocToolStripMenuItem.Click += new System.EventHandler(this.SimpleDocToolStripMenuItem_Click);
//
// TableDocToolStripMenuItem
//
this.TableDocToolStripMenuItem.Name = "TableDocToolStripMenuItem";
this.TableDocToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.T)));
this.TableDocToolStripMenuItem.Size = new System.Drawing.Size(233, 22);
this.TableDocToolStripMenuItem.Text = "Документ с таблицей";
this.TableDocToolStripMenuItem.Click += new System.EventHandler(this.TableDocToolStripMenuItem_Click);
//
// ChartDocToolStripMenuItem
//
this.ChartDocToolStripMenuItem.Name = "ChartDocToolStripMenuItem";
this.ChartDocToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
this.ChartDocToolStripMenuItem.Size = new System.Drawing.Size(233, 22);
this.ChartDocToolStripMenuItem.Text = "Диаграмма";
this.ChartDocToolStripMenuItem.Click += new System.EventHandler(this.ChartDocToolStripMenuItem_Click);
//
// panelControl
//
this.panelControl.Dock = System.Windows.Forms.DockStyle.Fill;
this.panelControl.Location = new System.Drawing.Point(0, 24);
this.panelControl.Name = "panelControl";
this.panelControl.Size = new System.Drawing.Size(800, 426);
this.panelControl.TabIndex = 1;
//
// ThesaurusToolStripMenuItem
//
this.ThesaurusToolStripMenuItem.Name = "ThesaurusToolStripMenuItem";
this.ThesaurusToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.I)));
this.ThesaurusToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.ThesaurusToolStripMenuItem.Text = "Справочник";
this.ThesaurusToolStripMenuItem.Click += new System.EventHandler(this.ThesaurusToolStripMenuItem_Click);
//
// AddElementToolStripMenuItem
//
this.AddElementToolStripMenuItem.Name = "AddElementToolStripMenuItem";
this.AddElementToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A)));
this.AddElementToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.AddElementToolStripMenuItem.Text = "Добавить";
this.AddElementToolStripMenuItem.Click += new System.EventHandler(this.AddElementToolStripMenuItem_Click);
//
// UpdElementToolStripMenuItem
//
this.UpdElementToolStripMenuItem.Name = "UpdElementToolStripMenuItem";
this.UpdElementToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.U)));
this.UpdElementToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.UpdElementToolStripMenuItem.Text = "Изменить";
this.UpdElementToolStripMenuItem.Click += new System.EventHandler(this.UpdElementToolStripMenuItem_Click);
//
// DelElementToolStripMenuItem
//
this.DelElementToolStripMenuItem.Name = "DelElementToolStripMenuItem";
this.DelElementToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.D)));
this.DelElementToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.DelElementToolStripMenuItem.Text = "Удалить";
this.DelElementToolStripMenuItem.Click += new System.EventHandler(this.DelElementToolStripMenuItem_Click);
//
// FormMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.panelControl);
this.Controls.Add(this.menuStrip);
this.MainMenuStrip = this.menuStrip;
this.Name = "FormMain";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Главная форма";
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.FormMain_KeyDown);
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem ControlsStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem DocsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem SimpleDocToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem TableDocToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem ChartDocToolStripMenuItem;
private System.Windows.Forms.Panel panelControl;
private System.Windows.Forms.ToolStripMenuItem ActionsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem ThesaurusToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem AddElementToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem UpdElementToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem DelElementToolStripMenuItem;
}
}

View File

@ -0,0 +1,309 @@
using DocumentFormat.OpenXml.Office2010.CustomUI;
using Plugins;
using System.Reflection;
namespace WinFormsPlugins
{
/// <summary>
/// Ãëàâíàÿ ôîðìà
/// </summary>
public partial class FormMain : Form
{
/// <summary>
/// Ïëàãèíû
/// </summary>
private readonly Dictionary<string, IPluginsConvention> _plugins;
/// <summary>
/// Âûáðàííûé ïëàãèí
/// </summary>
private string _selectedPlugin;
/// <summary>
/// Êîíñòðóêòîð
/// </summary>
public FormMain()
{
InitializeComponent();
_plugins = LoadPlugins();
_selectedPlugin = string.Empty;
}
/// <summary>
/// Çàãðóçêà ïëàãèíîâ
/// </summary>
/// <returns></returns>
private Dictionary<string, IPluginsConvention> LoadPlugins()
{
var plugins = new Dictionary<string, IPluginsConvention>();
string pluginsDir = Directory.GetParent(Directory.GetCurrentDirectory())!
.Parent!.Parent!.FullName + "\\plugins";
string[] dllFiles = Directory.GetFiles(pluginsDir, "*.dll", SearchOption.AllDirectories);
foreach (string dllFile in dllFiles)
{
try
{
Assembly assembly = Assembly.LoadFrom(dllFile);
Type[] types = assembly.GetTypes();
foreach (var type in types)
{
if (typeof(IPluginsConvention).IsAssignableFrom(type) && !type.IsInterface)
{
var plugin = (IPluginsConvention)Activator.CreateInstance(type)!;
plugins.Add(plugin.PluginName, plugin);
CreateToolStripMenuItem(plugin.PluginName);
}
}
}
catch (Exception ex)
{
// Ïðîñòè, Ãîñïîäè, ãðåøíèêà, çà òî, ÷òî ïðÿ÷ó âûëåçàþùèå Exceptions, íî ÿ íå íàø¸ë êàê èõ ïîôèêñèòü
// Unable to load one or more of the requested types
Console.WriteLine($"Îøèáêà ïðè çàãðóçêå ñáîðêè {dllFile}: {ex.Message}");
}
}
return plugins;
}
/// <summary>
/// Ñîçäàòü ToolStripMenuItem äëÿ ïëàãèíà
/// </summary>
/// <param name="pluginName"></param>
private void CreateToolStripMenuItem(string pluginName)
{
var menuItem = new ToolStripMenuItem(pluginName);
menuItem.Click += (object? sender, EventArgs e) =>
{
_selectedPlugin = pluginName;
IPluginsConvention plugin = _plugins![pluginName];
UserControl userControl = plugin.GetControl;
if (userControl != null)
{
panelControl.Controls.Clear();
plugin.ReloadData();
userControl.Dock = DockStyle.Fill;
panelControl.Controls.Add(userControl);
}
};
ControlsStripMenuItem.DropDownItems.Add(menuItem);
}
/// <summary>
/// Îáðàáîòêà íàæàòèÿ êíîïîê
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormMain_KeyDown(object sender, KeyEventArgs e)
{
if (string.IsNullOrEmpty(_selectedPlugin) || !_plugins.ContainsKey(_selectedPlugin))
{
return;
}
if (!e.Control)
{
return;
}
switch (e.KeyCode)
{
case Keys.I:
ShowThesaurus();
break;
case Keys.A:
AddNewElement();
break;
case Keys.U:
UpdateElement();
break;
case Keys.D:
DeleteElement();
break;
case Keys.S:
CreateSimpleDoc();
break;
case Keys.T:
CreateTableDoc();
break;
case Keys.C:
CreateChartDoc();
break;
}
}
/// <summary>
/// Îòîáðàçèòü ôîðìó äëÿ ðàáîòû ñî ñïðàâî÷íèêîì
/// </summary>
private void ShowThesaurus()
{
_plugins[_selectedPlugin].GetThesaurus()?.Show();
}
/// <summary>
/// Ñîçäàòü ýëåìåíò
/// </summary>
private void AddNewElement()
{
var form = _plugins[_selectedPlugin].GetForm(null);
if (form != null && form.ShowDialog() == DialogResult.OK)
{
_plugins[_selectedPlugin].ReloadData();
}
}
/// <summary>
/// Ðåäàêòèðîâàòü ýëåìåíò
/// </summary>
private void UpdateElement()
{
var element = _plugins[_selectedPlugin].GetElement;
if (element == null)
{
MessageBox.Show("Íåò âûáðàííîãî ýëåìåíòà!", "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
var form = _plugins[_selectedPlugin].GetForm(element);
if (form != null && form.ShowDialog() == DialogResult.OK)
{
_plugins[_selectedPlugin].ReloadData();
}
}
/// <summary>
/// Óäàëèòü ýëåìåíò
/// </summary>
private void DeleteElement()
{
var element = _plugins[_selectedPlugin].GetElement;
if (element == null)
{
MessageBox.Show("Íåò âûáðàííîãî ýëåìåíòà!", "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (_plugins[_selectedPlugin].DeleteElement(element))
{
_plugins[_selectedPlugin].ReloadData();
}
}
/// <summary>
/// Ñîçäàòü ïðîñòîé äîêóìåíò
/// </summary>
private void CreateSimpleDoc()
{
using (var dialog = new SaveFileDialog { Filter = "xlsx|*.xlsx" })
{
if (dialog.ShowDialog() == DialogResult.OK)
{
string fileName = dialog.FileName.ToString();
if (_plugins[_selectedPlugin].CreateSimpleDocument(new PluginsConventionSaveDocument() { FileName = fileName }))
{
MessageBox.Show("Äîêóìåíò ñîõðàíåí", "Ñîçäàíèå äîêóìåíòà", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Îøèáêà ïðè ñîçäàíèè äîêóìåíòà", "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
/// <summary>
/// Ñîçäàòü äîêóìåíò ñ íàñòðàèâàåìîé òàáëèöåé
/// </summary>
private void CreateTableDoc()
{
using (var dialog = new SaveFileDialog { Filter = "docx|*.docx" })
{
if (dialog.ShowDialog() == DialogResult.OK)
{
string fileName = dialog.FileName.ToString();
if (_plugins[_selectedPlugin].CreateTableDocument(new PluginsConventionSaveDocument() { FileName = fileName }))
{
MessageBox.Show("Äîêóìåíò ñîõðàíåí", "Ñîçäàíèå äîêóìåíòà", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Îøèáêà ïðè ñîçäàíèè äîêóìåíòà", "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
/// <summary>
/// Ñîçäàòü äîêóìåíò ñ äèàãðàììîé
/// </summary>
private void CreateChartDoc()
{
using (var dialog = new SaveFileDialog { Filter = "pdf|*.pdf" })
{
if (dialog.ShowDialog() == DialogResult.OK)
{
string fileName = dialog.FileName.ToString();
if (_plugins[_selectedPlugin].CreateChartDocument(new PluginsConventionSaveDocument() { FileName = fileName }))
{
MessageBox.Show("Äîêóìåíò ñîõðàíåí", "Ñîçäàíèå äîêóìåíòà", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Îøèáêà ïðè ñîçäàíèè äîêóìåíòà", "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
/// <summary>
/// Îòîáðàçèòü ôîðìó äëÿ ðàáîòû ñî ñïðàâî÷íèêîì
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ThesaurusToolStripMenuItem_Click(object sender, EventArgs e) => ShowThesaurus();
/// <summary>
/// Ñîçäàòü ýëåìåíò
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void AddElementToolStripMenuItem_Click(object sender, EventArgs e) => AddNewElement();
/// <summary>
/// Ðåäàêòèðîâàòü ýëåìåíò
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void UpdElementToolStripMenuItem_Click(object sender, EventArgs e) => UpdateElement();
/// <summary>
/// Óäàëèòü ýëåìåíò
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DelElementToolStripMenuItem_Click(object sender, EventArgs e) => DeleteElement();
/// <summary>
/// Ñîçäàòü ïðîñòîé äîêóìåíò
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SimpleDocToolStripMenuItem_Click(object sender, EventArgs e) => CreateSimpleDoc();
/// <summary>
/// Ñîçäàòü äîêóìåíò ñ íàñòðàèâàåìîé òàáëèöåé
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TableDocToolStripMenuItem_Click(object sender, EventArgs e) => CreateTableDoc();
/// <summary>
/// Ñîçäàòü äîêóìåíò ñ äèàãðàììîé
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ChartDocToolStripMenuItem_Click(object sender, EventArgs e) => CreateChartDoc();
}
}

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,25 @@
using BusinessLogics.BusinessLogics;
using Contracts.BusinessLogicsContracts;
using Contracts.StoragesContracts;
using DatabaseImplement.Implements;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
namespace WinFormsPlugins
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new FormMain());
}
}
}

View File

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Components\Components.csproj" />
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\Plugins\Plugins.csproj" />
<ProjectReference Include="..\WinForms\WinForms.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="plugins\" />
</ItemGroup>
</Project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More