Compare commits

...

5 Commits
main ... Lab4

Author SHA1 Message Date
Andrey
6e7ab4f698 сдал 2024-10-27 18:58:38 +03:00
Andrey
358a381e20 Вроде готово, потом мб поправлю 2024-10-16 13:08:07 +03:00
Andrey
82d134aeab переделал на net6 2024-10-02 11:38:48 +03:00
Andrey
361c46c4b6 Приняты 1+2 2024-09-20 10:29:21 +03:00
Andrey
9ee931a747 Working (mb need fixes) 2024-09-19 21:22:23 +03:00
135 changed files with 7538 additions and 0 deletions

View File

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\DataModels\DataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,163 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
using Contracts.SearchModels;
using Contracts.StorageContracts;
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
{
public class DishLogic : IDishLogic
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Хранилище
/// </summary>
private readonly IDishStorage _dishStorage;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="dishStorage"></param>
public DishLogic(ILogger<DishLogic> logger, IDishStorage dishStorage)
{
_logger = logger;
_dishStorage = dishStorage;
}
/// <summary>
/// Получить список записией
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<DishViewModel>? ReadList(DishSearchModel? model)
{
_logger.LogInformation("ReadList. Dish.Id: {Id}", model?.Id);
var list = model == null ? _dishStorage.GetFullList() : _dishStorage.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 DishViewModel? ReadElement(DishSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Dish.Id: {Id}", model?.Id);
var element = _dishStorage.GetElement(model!);
if (element == null)
{
_logger.LogWarning("ReadElement. Element not found");
return null;
}
_logger.LogInformation("ReadElement. Find Dish.Id: {Id}", element.Id);
return element;
}
/// <summary>
/// Создать запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public bool Create(DishBindingModel model)
{
CheckModel(model);
_logger.LogInformation("Create. Dish.Id: {Id}", model.Id);
if (_dishStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
/// <summary>
/// Изменить запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public bool Update(DishBindingModel model)
{
CheckModel(model);
_logger.LogInformation("Update. Dish.Id: {Id}", model.Id);
if (_dishStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
/// <summary>
/// Удалить запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public bool Delete(DishBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Dish.Id: {Id}", model.Id);
if (_dishStorage.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(DishBindingModel 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. Dish.Id: {Id}", model.Id);
}
}
}

View File

@ -0,0 +1,166 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
using Contracts.SearchModels;
using Contracts.StorageContracts;
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
{
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;
}
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.Dish))
{
throw new ArgumentNullException("Не указано заказанное блюдо", nameof(model.Dish));
}
if (string.IsNullOrEmpty(model.PicturePath))
{
throw new ArgumentNullException("Не указан скан счета", nameof(model.PicturePath));
}
_logger.LogInformation("CheckModel. Order.Id: {Id}", model.Id);
}
}
}

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PDFsharp-MigraDoc" Version="6.1.1" />
</ItemGroup>
</Project>

70
Components/Components.sln Normal file
View File

@ -0,0 +1,70 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35222.181
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Components", "Components.csproj", "{81DCA34B-4D91-4C79-A0CC-65F1DB3BCC18}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BusinessLogics", "..\BusinessLogics\BusinessLogics.csproj", "{9CAF8B8B-62FC-49BB-BFAF-A041B00DC273}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contracts", "..\Contracts\Contracts.csproj", "{F92B9F62-A158-4AFF-A89E-A1F3535A3938}"
ProjectSection(ProjectDependencies) = postProject
{FB13C40F-4FBA-4A3E-970B-B819088AF3C5} = {FB13C40F-4FBA-4A3E-970B-B819088AF3C5}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DatabaseImplement", "..\DatabaseImplement\DatabaseImplement.csproj", "{76CE2845-2A17-4AB2-B858-E5C59D9BAAC3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataModels", "..\DataModels\DataModels.csproj", "{FB13C40F-4FBA-4A3E-970B-B819088AF3C5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinForms", "..\WinForms\WinForms.csproj", "{A76DC396-93E5-4901-9A18-0E7590457772}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugins", "..\Plugins\Plugins.csproj", "{B3121C82-27B5-4815-A282-60980964567E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinFormsPlugin", "..\WinFormsPlugin\WinFormsPlugin.csproj", "{6AB7FD14-0E3B-47E9-90FE-5B8D8A6A359F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{81DCA34B-4D91-4C79-A0CC-65F1DB3BCC18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81DCA34B-4D91-4C79-A0CC-65F1DB3BCC18}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81DCA34B-4D91-4C79-A0CC-65F1DB3BCC18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81DCA34B-4D91-4C79-A0CC-65F1DB3BCC18}.Release|Any CPU.Build.0 = Release|Any CPU
{9CAF8B8B-62FC-49BB-BFAF-A041B00DC273}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9CAF8B8B-62FC-49BB-BFAF-A041B00DC273}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9CAF8B8B-62FC-49BB-BFAF-A041B00DC273}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9CAF8B8B-62FC-49BB-BFAF-A041B00DC273}.Release|Any CPU.Build.0 = Release|Any CPU
{F92B9F62-A158-4AFF-A89E-A1F3535A3938}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F92B9F62-A158-4AFF-A89E-A1F3535A3938}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F92B9F62-A158-4AFF-A89E-A1F3535A3938}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F92B9F62-A158-4AFF-A89E-A1F3535A3938}.Release|Any CPU.Build.0 = Release|Any CPU
{76CE2845-2A17-4AB2-B858-E5C59D9BAAC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{76CE2845-2A17-4AB2-B858-E5C59D9BAAC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{76CE2845-2A17-4AB2-B858-E5C59D9BAAC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{76CE2845-2A17-4AB2-B858-E5C59D9BAAC3}.Release|Any CPU.Build.0 = Release|Any CPU
{FB13C40F-4FBA-4A3E-970B-B819088AF3C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FB13C40F-4FBA-4A3E-970B-B819088AF3C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FB13C40F-4FBA-4A3E-970B-B819088AF3C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FB13C40F-4FBA-4A3E-970B-B819088AF3C5}.Release|Any CPU.Build.0 = Release|Any CPU
{A76DC396-93E5-4901-9A18-0E7590457772}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A76DC396-93E5-4901-9A18-0E7590457772}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A76DC396-93E5-4901-9A18-0E7590457772}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A76DC396-93E5-4901-9A18-0E7590457772}.Release|Any CPU.Build.0 = Release|Any CPU
{B3121C82-27B5-4815-A282-60980964567E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B3121C82-27B5-4815-A282-60980964567E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B3121C82-27B5-4815-A282-60980964567E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B3121C82-27B5-4815-A282-60980964567E}.Release|Any CPU.Build.0 = Release|Any CPU
{6AB7FD14-0E3B-47E9-90FE-5B8D8A6A359F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6AB7FD14-0E3B-47E9-90FE-5B8D8A6A359F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6AB7FD14-0E3B-47E9-90FE-5B8D8A6A359F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6AB7FD14-0E3B-47E9-90FE-5B8D8A6A359F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2984512D-D991-4B14-8074-FCDA2BC9A8DF}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.Components.NonVisualComponents.HelperModels
{
public class DataForImage
{
public DataForImage(string filepath, string header, string[] imagepaths)
{
this.filepath = filepath;
this.header = header;
this.imagepaths = imagepaths;
}
public string filepath;
public string header;
public string[] imagepaths;
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.Components.NonVisualComponents.HelperModels
{
public class DataForPieChart
{
public string FilePath = string.Empty;
public string DocumentTitle = string.Empty;//заголовок документа
public string ChartTitle = string.Empty;//заголовок диаграммы
public DiagramLegendEnum diagLegend;
public string LegendName = string.Empty;
public List<(double, string)> Items;
public DataForPieChart(string filePath, string documentTitle, string charttitle, DiagramLegendEnum diagLegend, string legendName, List<(double, string)> items)
{
FilePath = filePath;
DocumentTitle = documentTitle;
ChartTitle = charttitle;
this.diagLegend = diagLegend;
LegendName = legendName;
Items = items;
}
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.Components.NonVisualComponents.HelperModels
{
public class DataForTable<T>
{
public string FilePath = string.Empty;
public string DocumentTitle = string.Empty; //заголовок документа
public List<int> Heights; // высота строк
public List<(int, int)> Merges; // информаци о объединении ячеек
public List<(string props, string heads)> Headers; //заголовки шапки таблицы
public List<T> Data;
public DataForTable(string filePath, string documentTitle, List<int> heights, List<(int, int)> merges, List<(string, string)> headers, List<T> data)
{
FilePath = filePath;
DocumentTitle = documentTitle;
Heights = heights;
Merges = merges;
Headers = headers;
Data = data;
}
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.Components.NonVisualComponents.HelperModels
{
public enum DiagramLegendEnum
{
Top = 0,
Bottom = 1,
Right = 2,
Left = 3,
}
}

View File

@ -0,0 +1,36 @@
namespace Components.Components.NonVisualComponents
{
partial class PdfImage
{
/// <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,75 @@
using Components.Components.NonVisualComponents.HelperModels;
using MigraDoc.DocumentObjectModel;
using MigraDoc.Rendering;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Components.Components.NonVisualComponents
{
public partial class PdfImage : Component
{
public PdfImage()
{
InitializeComponent();
}
public PdfImage(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public bool CreatePdfDoc(DataForImage dataForImage)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
CheckFileExsists(dataForImage);
// создание документа
Document _document = new Document();
var style = _document.Styles["Normal"];
style.Font.Name = "Arial";
style.Font.Size = 25;
style = _document.Styles.AddStyle("NormalTitle", "Normal");
style.Font.Bold = true;
//добавление заголовка
var section = _document.AddSection();
var paragraph = section.AddParagraph(dataForImage.header);
paragraph.Format.Alignment = ParagraphAlignment.Center;
paragraph.Format.SpaceAfter = "2cm";
//добавление изображений
foreach (string path in dataForImage.imagepaths)
if (File.Exists(path)) section.AddImage(path);
//сохранение документа
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true);
renderer.Document = _document;
renderer.RenderDocument();
renderer.PdfDocument.Save(dataForImage.filepath);
return true;
}
private void CheckFileExsists(DataForImage dataForImage)
{
if (string.IsNullOrEmpty(dataForImage.filepath) || string.IsNullOrEmpty(dataForImage.header) || dataForImage.imagepaths.Length == 0)
{
throw new ArgumentNullException();
}
if (!File.Exists(dataForImage.filepath))
{
throw new FileNotFoundException(dataForImage.filepath);
}
}
}
}

View File

@ -0,0 +1,36 @@
namespace Components.Components.NonVisualComponents
{
partial class PdfPieChart
{
/// <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,86 @@
using Components.Components.NonVisualComponents.HelperModels;
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Shapes.Charts;
using MigraDoc.Rendering;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.Components.NonVisualComponents
{
public partial class PdfPieChart : Component
{
public PdfPieChart()
{
InitializeComponent();
}
public PdfPieChart(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public bool CreatePieChart(DataForPieChart dataForPDFPie)
{
// проверки
if (string.IsNullOrEmpty(dataForPDFPie.FilePath) || string.IsNullOrEmpty(dataForPDFPie.DocumentTitle) || string.IsNullOrEmpty(dataForPDFPie.ChartTitle)
|| string.IsNullOrEmpty(dataForPDFPie.LegendName)
|| dataForPDFPie.Items.Count == 0) throw new ArgumentException("Недостаточно данных");
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Document _document = new Document();
var section = _document.AddSection();
var paragraph = section.AddParagraph(dataForPDFPie.DocumentTitle);
paragraph.Format.Alignment = ParagraphAlignment.Center;
paragraph.Format.SpaceAfter = "2cm";
Chart chart = section.AddChart(ChartType.Pie2D);
chart.Width = Unit.FromCentimeter(16);
chart.Height = Unit.FromCentimeter(12);
chart.HeaderArea.AddParagraph(dataForPDFPie.ChartTitle); // заголовок диаграммы
Series series = chart.SeriesCollection.AddSeries();
series.Name = dataForPDFPie.LegendName; // название сериии
XSeries xseries = chart.XValues.AddXSeries();
foreach ((double, string) el in dataForPDFPie.Items) // заполнение серии
{
series.Add(el.Item1);
xseries.Add(el.Item2);
}
switch (dataForPDFPie.diagLegend) // позиция легенды
{
case DiagramLegendEnum.Top:
chart.TopArea.AddLegend();
break;
case DiagramLegendEnum.Bottom:
chart.BottomArea.AddLegend();
break;
case DiagramLegendEnum.Right:
chart.RightArea.AddLegend();
break;
case DiagramLegendEnum.Left:
chart.LeftArea.AddLegend();
break;
}
chart.DataLabel.Type = DataLabelType.Percent;
chart.DataLabel.Position = DataLabelPosition.OutsideEnd;
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true);
renderer.Document = _document;
renderer.RenderDocument();
renderer.PdfDocument.Save(dataForPDFPie.FilePath);
return true;
}
}
}

View File

@ -0,0 +1,36 @@
namespace Components.Components.NonVisualComponents
{
partial class PdfTable
{
/// <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,178 @@
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.DocumentObjectModel;
using MigraDoc.Rendering;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Components.Components.NonVisualComponents.HelperModels;
namespace Components.Components.NonVisualComponents
{
public partial class PdfTable : Component
{
public PdfTable()
{
InitializeComponent();
}
public PdfTable(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public bool createTable<T>(DataForTable<T> dataForPDF)
{
//проверки
if (dataForPDF.Merges.Count == 0 || dataForPDF.Heights.Count == 0 || dataForPDF.Headers.Count == 0
|| dataForPDF.Data.Count == 0 || string.IsNullOrEmpty(dataForPDF.FilePath)
|| string.IsNullOrEmpty(dataForPDF.DocumentTitle)) throw new ArgumentException("Недостаточно данных");
int[] cellsArray = new int[dataForPDF.Heights.Count];
foreach (var merge in dataForPDF.Merges)
{
if (merge.Item1 >= merge.Item2) throw new ArgumentException("Неправильно заполнены объединения строк");
for (int i = merge.Item1; i < merge.Item2; i++)
{
cellsArray[i]++;
}
}
foreach (int cell in cellsArray)
{
if (cell > 1) throw new ArgumentException("Объединения заходят друг на друга");
}
foreach ((string, string) el in dataForPDF.Headers)
if (string.IsNullOrEmpty(el.Item2)) throw new ArgumentException("Элементы шапки не могут быть пустыми");
//создание документа
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Document _document = new Document();
var style = _document.Styles["Normal"];
style = _document.Styles.AddStyle("NormalTitle", "Normal");
style.Font.Name = "Arial";
style.Font.Size = 25;
style.Font.Bold = true;
style = _document.Styles.AddStyle("Table", "Normal");
style.Font.Name = "Times New Roman";
style.Font.Size = 12;
//добавление заголовка
var section = _document.AddSection();
var paragraph = section.AddParagraph(dataForPDF.DocumentTitle);
paragraph.Format.Alignment = ParagraphAlignment.Center;
paragraph.Format.SpaceAfter = "2cm";
paragraph.Style = "NormalTitle";
//добавление таблицы
Table table = section.AddTable();
table.Style = "Table";
table.Borders.Width = 0.25;
Column column;
for (int i = 0; i < dataForPDF.Data.Count + 2; i++)
{
column = table.AddColumn();
column.Format.Alignment = ParagraphAlignment.Center;
}
// создание шапки и заполнение контентом
int mergeRange = 0; //размерность слияния
int mergeIndex = 0; //стартовый индекс начала слияния
Row row;
for (int i = 0; i < dataForPDF.Headers.Count; i++)
{
//если элемент шапки группируются по строкам
if (dataForPDF.Merges.Select(x => x.Item1).Contains(mergeIndex))
{
mergeRange = dataForPDF.Merges.Find(x => x.Item1 == mergeIndex).Item2 - mergeIndex;
mergeIndex = dataForPDF.Merges.Find(x => x.Item1 == mergeIndex).Item2 + 1;
//стилизация ячейки. в этом блоке кода (до цикла) создаётся объединяющая ячейка
row = table.AddRow();
row.Height = dataForPDF.Heights[i];
row.Format.Alignment = ParagraphAlignment.Center;
row.Format.Font.Bold = true;
row.Cells[0].AddParagraph(dataForPDF.Headers[i].Item2);
row.Cells[0].VerticalAlignment = VerticalAlignment.Center;
row.Cells[0].MergeDown = mergeRange;
//с этого места создаются дочерние ячейки
for (int k = 0; k < mergeRange; k++)
{
i++;
row.Cells[1].AddParagraph(dataForPDF.Headers[i].Item2);
AddTheContent<T>(dataForPDF.Data, table, dataForPDF.Headers[i].Item1, row.Index, 2);
row.Cells[1].VerticalAlignment = VerticalAlignment.Center;
row = table.AddRow();
row.Height = dataForPDF.Heights[i];
row.Format.Font.Bold = true;
row.Format.Alignment = ParagraphAlignment.Center;
}
i++;
row.Cells[1].AddParagraph(dataForPDF.Headers[i].Item2);
AddTheContent<T>(dataForPDF.Data, table, dataForPDF.Headers[i].Item1, row.Index, 2);
row.Cells[1].VerticalAlignment = VerticalAlignment.Center;
}
else //если элемент шапки не группируется по строкам
{
//стилизация ячейки
row = table.AddRow();
row.Height = dataForPDF.Heights[i];
row.Format.Font.Bold = true;
row.Format.Alignment = ParagraphAlignment.Center;
row.Cells[0].AddParagraph(dataForPDF.Headers[i].Item2);
row.Cells[0].VerticalAlignment = VerticalAlignment.Center;
row.Cells[0].MergeRight = 1;
AddTheContent<T>(dataForPDF.Data, table, dataForPDF.Headers[i].Item1, row.Index, 2);
mergeIndex++;
}
}
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true);
renderer.Document = _document;
renderer.RenderDocument();
renderer.PdfDocument.Save(dataForPDF.FilePath);
return true;
}
//метод заполнения таблицы контентом, заполнение происходит построчно.
public void AddTheContent<T>(List<T> items, Table table, string header, int row_index, int cell_index)
{
foreach (Row r in table.Rows)
{
for (int i = 0; i < items.Count; i++)
{
if (r.Index == row_index && row_index == 0) r.Cells[cell_index + i].AddParagraph((i + 1).ToString());
else if (row_index != 0 && r.Index == row_index)
{
T item = items[i];
var type = typeof(T);
var fields = type.GetFields();
var field = fields.FirstOrDefault(x => x.Name.Equals(header));
r.Cells[cell_index + i].AddParagraph(field.GetValue(item).ToString());
r.Cells[cell_index + i].VerticalAlignment = VerticalAlignment.Center;
}
}
}
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.Components.VisualComponents.Classes
{
public class Character
{
public string? Race { get; set; }
public string? Class { get; set; }
public string? FullName { get; set; }
}
}

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.Components.VisualComponents.Classes
{
public class CharacterInfo
{
public string Age;
public string Name;
public string AKA;
public string Height;
public string Weight;
public CharacterInfo(string age, string name, string aka, string height, string weight)
{
Age = age;
Name = name;
AKA = aka;
Height = height;
Weight = weight;
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.Components.VisualComponents.Exceptions
{
public class WrongRangeException : Exception
{
public WrongRangeException() { }
public WrongRangeException(string message) : base(message) { }
public WrongRangeException(string message, Exception inner) : base(message, inner) { }
}
}

View File

@ -0,0 +1,58 @@
namespace Components
{
partial class UserCheckedListBox
{
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
checkedListBox = new CheckedListBox();
SuspendLayout();
//
// checkedListBox
//
checkedListBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
checkedListBox.CheckOnClick = true;
checkedListBox.FormattingEnabled = true;
checkedListBox.Location = new Point(3, 3);
checkedListBox.Name = "checkedListBox";
checkedListBox.Size = new Size(144, 136);
checkedListBox.TabIndex = 0;
checkedListBox.SelectedIndexChanged += this.checkedListBox_SelectedIndexChanged;
//
// UserCheckedListBox
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(checkedListBox);
Name = "UserCheckedListBox";
ResumeLayout(false);
}
#endregion
private CheckedListBox checkedListBox;
}
}

View File

@ -0,0 +1,79 @@
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
{
public partial class UserCheckedListBox : UserControl
{
public UserCheckedListBox()
{
InitializeComponent();
}
private EventHandler _changeEvent;
private void checkedListBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (checkedListBox.CheckedItems.Count > 1)
{
foreach (int index in checkedListBox.CheckedIndices)
{
if (index != checkedListBox.SelectedIndex)
{
checkedListBox.SetItemChecked(index, false);
}
}
}
_changeEvent?.Invoke(sender, e);
}
public event EventHandler ChangeEvent
{
add
{
_changeEvent += value;
}
remove
{
_changeEvent -= value;
}
}
public void Clear()
{
checkedListBox.Items.Clear();
}
public void AddToList(string Value)
{
if (Value == null)
{
return;
}
checkedListBox.Items.Add(Value);
}
public string SelectedElement
{
get
{
return checkedListBox.SelectedItem?.ToString() ?? string.Empty;
}
set
{
if (checkedListBox.Items.Contains(value))
{
checkedListBox.SelectedItem = value;
}
}
}
}
}

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,58 @@
namespace Components.Components.VisualComponents
{
partial class UserTextBox
{
/// <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();
SuspendLayout();
//
// textBox
//
textBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
textBox.Location = new Point(5, 15);
textBox.Name = "textBox";
textBox.Size = new Size(309, 27);
textBox.TabIndex = 0;
textBox.TextChanged += textBox_TextChanged;
//
// UserTextBox
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(textBox);
Name = "UserTextBox";
Size = new Size(317, 61);
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBox;
}
}

View File

@ -0,0 +1,84 @@
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 Components.Components.VisualComponents.Exceptions;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace Components.Components.VisualComponents
{
public partial class UserTextBox : UserControl
{
public UserTextBox()
{
InitializeComponent();
}
public int ?MinValue { get; set; }
public int ?MaxValue { get; set; }
private EventHandler _changeEvent;
public event EventHandler ChangeEvent
{
add
{
_changeEvent += value;
}
remove
{
_changeEvent -= value;
}
}
private void textBox_TextChanged(object sender, EventArgs e)
{
_changeEvent?.Invoke(sender, e);
if (MinValue != null && MaxValue != null)
{
if (textBox.Text.Length < MinValue || textBox.Text.Length > MaxValue)
{
textBox.ForeColor = Color.Red;
}
else
{
textBox.ForeColor = Color.Black;
}
}
}
public string TextBoxValue
{
get
{
if (MinValue == null && MaxValue == null)
{
throw new WrongRangeException("Диапазон не задан.");
}
if (textBox.Text.Length >= MinValue && textBox.Text.Length <= MaxValue)
{
return textBox.Text;
}
throw new WrongRangeException("Введенное значение не входит в диапазон.");
}
set
{
if (MinValue != null && MaxValue != null)
{
if (value.Length >= MinValue && value.Length <= MaxValue)
{
textBox.Text = value;
}
}
}
}
}
}

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,56 @@
namespace Components.Components.VisualComponents
{
partial class UserTreeView
{
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
treeView = new TreeView();
SuspendLayout();
//
// treeView
//
treeView.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
treeView.Location = new Point(0, 3);
treeView.Name = "treeView";
treeView.Size = new Size(440, 257);
treeView.TabIndex = 0;
//
// UserTreeView
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(treeView);
Name = "UserTreeView";
Size = new Size(440, 263);
ResumeLayout(false);
}
#endregion
private TreeView treeView;
}
}

View File

@ -0,0 +1,97 @@
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 System.Reflection;
namespace Components.Components.VisualComponents
{
public partial class UserTreeView : UserControl
{
private List<string> hierarchy;
public UserTreeView()
{
InitializeComponent();
hierarchy = new List<string>();
}
public void SetHierarchy(List<string> hierarchy)
{
this.hierarchy = hierarchy;
}
public void AddObjectToTree<T>(T obj)
{
TreeNode currentNode = treeView.Nodes.Count > 0 ? treeView.Nodes[0] : treeView.Nodes.Add("");
foreach (var property in hierarchy)
{
var value = obj.GetType().GetProperty(property).GetValue(obj, null).ToString();
var childNode = currentNode.Nodes.Cast<TreeNode>().FirstOrDefault(n => n.Text == value);
if (childNode == null)
{
childNode = currentNode.Nodes.Add(value);
}
currentNode = childNode;
}
}
public int SelectedNodeIndex
{
get
{
return treeView.SelectedNode?.Index ?? -1;
}
set
{
if (value >= 0 && value < treeView.Nodes.Count)
{
treeView.SelectedNode = treeView.Nodes[value];
}
}
}
public T GetSelectedObject<T>() where T : new()
{
if (treeView.SelectedNode == null)
{
throw new InvalidOperationException("Узел не выбран");
}
var node = treeView.SelectedNode;
if (node.Nodes.Count != 0)
{
throw new InvalidOperationException("Узел не конечный, сформировать объект нельзя");
}
var obj = new T();
foreach (var property in hierarchy)
{
var value = node.Text;
var propInfo = typeof(T).GetProperty(property);
if (propInfo == null)
{
throw new InvalidOperationException($"Свойство {property} не найдено в классе {typeof(T).Name}");
}
propInfo.SetValue(obj, Convert.ChangeType(value, propInfo.PropertyType));
node = node.Parent;
if (node == null)
{
break;
}
}
return obj;
}
}
}

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,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DataModels.Models;
namespace Contracts.BindingModels
{
public class DishBindingModel : IDishModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; set; }
/// <summary>
/// Название блюда
/// </summary>
public string Name { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,38 @@
using DataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.BindingModels
{
public class OrderBindingModel : IOrderModel
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; set; }
/// <summary>
/// ФИО официанта
/// </summary>
public string WaiterFullName { get; set; } = string.Empty;
/// <summary>
/// Информация по счету
/// </summary>
public string PicturePath { get; set; } = string.Empty;
/// <summary>
/// Тип заказа
/// </summary>
public string Dish { get; set; } = string.Empty;
/// <summary>
/// Сумма заказа
/// </summary>
public DateTime OrderDate { get; set; }
}
}

View File

@ -0,0 +1,50 @@
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
{
public interface IDishLogic
{
/// <summary>
/// Получить список записией
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
List<DishViewModel>? ReadList(DishSearchModel? model);
/// <summary>
/// Получить отдельную запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
DishViewModel? ReadElement(DishSearchModel model);
/// <summary>
/// Создать запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
bool Create(DishBindingModel model);
/// <summary>
/// Изменить запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
bool Update(DishBindingModel model);
/// <summary>
/// Удалить запись
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
bool Delete(DishBindingModel 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 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,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,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.SearchModels
{
public class DishSearchModel
{
public int? Id { get; set; }
public string? Name { 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 Contracts.SearchModels
{
public class OrderSearchModel
{
public int? Id { get; set; }
public string? WaiterFullName { get; set; }
public string Dish { get; set; }
public DateTime OrderDate { get; set; }
}
}

View File

@ -0,0 +1,26 @@
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.StorageContracts
{
public interface IDishStorage
{
List<DishViewModel> GetFullList();
List<DishViewModel> GetFilteredList(DishSearchModel model);
DishViewModel? GetElement(DishSearchModel model);
DishViewModel? Insert(DishBindingModel model);
DishViewModel? Update(DishBindingModel model);
DishViewModel? Delete(DishBindingModel model);
}
}

View File

@ -0,0 +1,27 @@
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.StorageContracts
{
public interface IOrderStorage
{
List<OrderViewModel> GetFullList();
List<OrderViewModel> GetFilteredList(OrderSearchModel model);
OrderViewModel? GetElement(OrderSearchModel model);
OrderViewModel? Insert(OrderBindingModel model);
OrderViewModel? Update(OrderBindingModel model);
OrderViewModel? Delete(OrderBindingModel model);
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.ViewModels
{
public class DishViewModel
{
public int Id { get; set; }
[DisplayName("Название блюда")]
public string Name { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.ViewModels
{
public class OrderViewModel
{
public int Id { get; set; }
[DisplayName("ФИО официанта")]
public string WaiterFullName { get; set; } = string.Empty;
[DisplayName("Заказанное блюдо")]
public string Dish { get; set; } = string.Empty;
public string PicturePath { get; set; } = string.Empty;
[DisplayName("Дата заказа")]
public DateTime OrderDate { 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>

20
DataModels/IId.cs Normal file
View File

@ -0,0 +1,20 @@
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,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace DataModels.Models
{
/// <summary>
/// Интерфейс для сущности "Заказанное блюдо"
/// </summary>
public interface IDishModel : IId
{
/// <summary>
/// Название блюда
/// </summary>
string Name { get; }
}
}

View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace DataModels.Models
{
/// <summary>
/// Интерфейс для сущности "Счет"
/// </summary>
public interface IOrderModel : IId
{
/// <summary>
/// ФИО официанта
/// </summary>
string WaiterFullName { get; }
/// <summary>
/// Путь до скана чека
/// </summary>
string PicturePath { get; }
/// <summary>
/// Заказанное блюдо
/// </summary>
string Dish { get; }
/// <summary>
/// Дата заказа
/// </summary>
DateTime OrderDate { get; }
}
}

View File

@ -0,0 +1,42 @@
using DatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement
{
public class Database : DbContext
{
/// <summary>
/// Параметры подключения к базе данных
/// </summary>
private string _dbConnectionString = "Host=localhost;Port=5432;Database=COPLabWorks;Username=postgres;Password=1111";
/// <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<Dish> Dishs { 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,126 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.StorageContracts;
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
{
public class DishStorage : IDishStorage
{
/// <summary>
/// Получить полный список элементов
/// </summary>
/// <returns></returns>
public List<DishViewModel> GetFullList()
{
using var context = new Database();
return context.Dishs
.Select(x => x.GetViewModel)
.ToList();
}
/// <summary>
/// Получить фильтрованный список элементов
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<DishViewModel> GetFilteredList(DishSearchModel model)
{
using var context = new Database();
// Фильтрация по названию типа
if (!string.IsNullOrEmpty(model.Name))
{
return context.Dishs
.Where(x => x.Name.Contains(model.Name))
.Select(x => x.GetViewModel)
.ToList();
}
return new();
}
/// <summary>
/// Получить элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public DishViewModel? GetElement(DishSearchModel model)
{
using var context = new Database();
if (model.Id.HasValue)
{
return context.Dishs
.FirstOrDefault(x => x.Id.Equals(model.Id))
?.GetViewModel;
}
return null;
}
/// <summary>
/// Добавить элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public DishViewModel? Insert(DishBindingModel model)
{
using var context = new Database();
var newDish = Dish.Create(model);
if (newDish == null)
{
return null;
}
context.Dishs.Add(newDish);
context.SaveChanges();
return newDish.GetViewModel;
}
/// <summary>
/// Редактировать элемент
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public DishViewModel? Update(DishBindingModel model)
{
using var context = new Database();
var orderType = context.Dishs
.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 DishViewModel? Delete(DishBindingModel model)
{
using var context = new Database();
var orderType = context.Dishs
.FirstOrDefault(x => x.Id.Equals(model.Id));
if (orderType == null)
{
return null;
}
context.Dishs.Remove(orderType);
context.SaveChanges();
return orderType.GetViewModel;
}
}
}

View File

@ -0,0 +1,135 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.StorageContracts;
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
{
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.Dish))
{
return context.Orders
.Where(x => x.Dish.Contains(model.Dish))
.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,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("20241004064731_init")]
partial class init
{
/// <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.Dish", 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("Dishs");
});
modelBuilder.Entity("DatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Dish")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("OrderDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("PicturePath")
.IsRequired()
.HasColumnType("text");
b.Property<string>("WaiterFullName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,55 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace DatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class init : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Dishs",
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_Dishs", x => x.Id);
});
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),
PicturePath = table.Column<string>(type: "text", nullable: false),
Dish = table.Column<string>(type: "text", nullable: false),
OrderDate = table.Column<DateTime>(type: "timestamp without time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Orders", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Dishs");
migrationBuilder.DropTable(
name: "Orders");
}
}
}

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.Dish", 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("Dishs");
});
modelBuilder.Entity("DatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Dish")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("OrderDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("PicturePath")
.IsRequired()
.HasColumnType("text");
b.Property<string>("WaiterFullName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,67 @@
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
{
public class Dish
{
public int Id { get; private set; }
[Required]
public string Name { get; private set; } = string.Empty;
public static Dish? Create(DishBindingModel model)
{
if (model == null)
{
return null;
}
return new Dish
{
Id = model.Id,
Name = model.Name,
};
}
public static Dish? Create(DishViewModel model)
{
if (model == null)
{
return null;
}
return new Dish
{
Id = model.Id,
Name = model.Name,
};
}
public void Update(DishBindingModel model)
{
if (model == null)
{
return;
}
Name = model.Name;
}
/// <summary>
/// Получить модель отображения
/// </summary>
public DishViewModel GetViewModel => new()
{
Id = Id,
Name = Name,
};
}
}

View File

@ -0,0 +1,76 @@
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
{
public class Order : IOrderModel
{
public int Id { get; private set; }
[Required]
public string WaiterFullName { get; private set; } = string.Empty;
[Required]
public string PicturePath { get; private set; } = string.Empty;
[Required]
public string Dish { get; private set; } = string.Empty;
[Required]
public DateTime OrderDate { get; private set; }
public static Order? Create(OrderBindingModel model)
{
if (model == null)
{
return null;
}
return new Order
{
Id = model.Id,
WaiterFullName = model.WaiterFullName,
PicturePath = model.PicturePath,
Dish = model.Dish,
OrderDate = model.OrderDate,
};
}
/// <summary>
/// Изменить модель
/// </summary>
/// <param name="model"></param>
public void Update(OrderBindingModel model)
{
if (model == null)
{
return;
}
WaiterFullName = model.WaiterFullName;
PicturePath = model.PicturePath;
Dish = model.Dish;
OrderDate = model.OrderDate;
}
/// <summary>
/// Получить модель отображения
/// </summary>
public OrderViewModel GetViewModel => new()
{
Id = Id,
WaiterFullName = WaiterFullName,
PicturePath = PicturePath,
Dish = Dish,
OrderDate = OrderDate,
};
}
}

View File

@ -0,0 +1,67 @@
namespace Plugins
{
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);
}
}

10
Plugins/Plugins.csproj Normal file
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,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Plugins
{
public class PluginsConventionElement
{
/// <summary>
/// Глобальный уникальный идентификатор
/// </summary>
public Guid Id { get; set; }
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Plugins
{
public class PluginsConventionSaveDocument
{
/// <summary>
/// Путь к файлу
/// </summary>
public string FileName { get; set; } = string.Empty;
}
}

69
TestForm/FormDish.Designer.cs generated Normal file
View File

@ -0,0 +1,69 @@
using System.Windows.Forms;
namespace WinForms
{
partial class FormDish
{
/// <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;
//
// FormDish
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(384, 211);
Controls.Add(dataGridView);
Name = "FormDish";
Text = "Блюда";
Load += FormDish_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
}
}

127
TestForm/FormDish.cs Normal file
View File

@ -0,0 +1,127 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
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
{
public partial class FormDish : Form
{
private readonly IDishLogic _dishLogic;
private BindingList<DishBindingModel> _bindingList;
public FormDish(IDishLogic dishLogic)
{
InitializeComponent();
_dishLogic = dishLogic;
_bindingList = new BindingList<DishBindingModel>();
}
private void FormDish_Load(object sender, EventArgs e)
{
LoadData();
}
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 DishBindingModel
{
Id = id,
Name = name
};
var operatingResult = id != 0 ? _dishLogic.Update(model) : _dishLogic.Create(model);
if (!operatingResult)
{
throw new Exception("Ошибка при создании сущности 'Заказанное блюдо'!");
}
}
else
{
MessageBox.Show("Введена пустая строка!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
LoadData();
}
private void dataGridView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Insert)
{
if (dataGridView.Rows.Count == 0)
{
_bindingList.Add(new DishBindingModel());
dataGridView.DataSource = new BindingList<DishBindingModel>(_bindingList);
dataGridView.CurrentCell = dataGridView.Rows[0].Cells[1];
return;
}
if (dataGridView.Rows[dataGridView.Rows.Count - 1].Cells[1].Value != null)
{
_bindingList.Add(new DishBindingModel());
dataGridView.DataSource = new BindingList<DishBindingModel>(_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)
{
_dishLogic.Delete(new DishBindingModel { Id = (int)dataGridView.CurrentRow.Cells[0].Value });
LoadData();
}
}
}
private void LoadData()
{
try
{
var types = _dishLogic.ReadList(null);
if (types == null)
{
return;
}
_bindingList.Clear();
foreach (var type in types)
{
_bindingList.Add(new DishBindingModel
{
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);
}
}
}
}

120
TestForm/FormDish.resx Normal file
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>

157
TestForm/FormMain.Designer.cs generated Normal file
View File

@ -0,0 +1,157 @@
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);
заказToolStripMenuItem = new ToolStripMenuItem();
созToolStripMenuItem = new ToolStripMenuItem();
редактироватьToolStripMenuItem = new ToolStripMenuItem();
удалитьToolStripMenuItem = new ToolStripMenuItem();
блюдоToolStripMenuItem = new ToolStripMenuItem();
документыToolStripMenuItem = new ToolStripMenuItem();
wordToolStripMenuItem = new ToolStripMenuItem();
excelToolStripMenuItem = new ToolStripMenuItem();
pdfToolStripMenuItem = new ToolStripMenuItem();
tableComponent = new Components.NonVisualComponents.TableComponent(components);
pdfImage = new Components.Components.NonVisualComponents.PdfImage(components);
componentDocumentWithChartBarWord = new ComponentsLibraryNet60.DocumentWithChart.ComponentDocumentWithChartBarWord(components);
controlDataListRow1 = new ControlsLibraryNet60.Data.ControlDataListRow();
contextMenuStrip.SuspendLayout();
SuspendLayout();
//
// contextMenuStrip
//
contextMenuStrip.ImageScalingSize = new Size(20, 20);
contextMenuStrip.Items.AddRange(new ToolStripItem[] { заказToolStripMenuItem, блюдоToolStripMenuItem, документыToolStripMenuItem });
contextMenuStrip.Name = "contextMenuStrip";
contextMenuStrip.Size = new Size(157, 76);
contextMenuStrip.Text = "Управление";
//
// заказToolStripMenuItem
//
заказToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { созToolStripMenuItem, редактироватьToolStripMenuItem, удалитьToolStripMenuItem });
заказToolStripMenuItem.Name = аказToolStripMenuItem";
заказToolStripMenuItem.Size = new Size(156, 24);
заказToolStripMenuItem.Text = "Заказ";
//
// созToolStripMenuItem
//
созToolStripMenuItem.Name = "созToolStripMenuItem";
созToolStripMenuItem.Size = new Size(194, 26);
созToolStripMenuItem.Text = "Создать";
созToolStripMenuItem.Click += созToolStripMenuItem_Click;
//
// редактироватьToolStripMenuItem
//
редактироватьToolStripMenuItem.Name = "редактироватьToolStripMenuItem";
редактироватьToolStripMenuItem.Size = new Size(194, 26);
редактироватьToolStripMenuItem.Text = "Редактировать";
редактироватьToolStripMenuItem.Click += редактироватьToolStripMenuItem_Click;
//
// удалитьToolStripMenuItem
//
удалитьToolStripMenuItem.Name = "удалитьToolStripMenuItem";
удалитьToolStripMenuItem.Size = new Size(194, 26);
удалитьToolStripMenuItem.Text = "Удалить";
удалитьToolStripMenuItem.Click += удалитьToolStripMenuItem_Click;
//
// блюдоToolStripMenuItem
//
блюдоToolStripMenuItem.Name = "блюдоToolStripMenuItem";
блюдоToolStripMenuItem.Size = new Size(156, 24);
блюдоToolStripMenuItem.Text = "Блюдо";
блюдоToolStripMenuItem.Click += блюдоToolStripMenuItem_Click;
//
// документыToolStripMenuItem
//
документыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { wordToolStripMenuItem, excelToolStripMenuItem, pdfToolStripMenuItem });
документыToolStripMenuItem.Name = окументыToolStripMenuItem";
документыToolStripMenuItem.Size = new Size(156, 24);
документыToolStripMenuItem.Text = "Документы";
//
// wordToolStripMenuItem
//
wordToolStripMenuItem.Name = "wordToolStripMenuItem";
wordToolStripMenuItem.Size = new Size(224, 26);
wordToolStripMenuItem.Text = "Word";
wordToolStripMenuItem.Click += wordToolStripMenuItem_Click;
//
// excelToolStripMenuItem
//
excelToolStripMenuItem.Name = "excelToolStripMenuItem";
excelToolStripMenuItem.Size = new Size(224, 26);
excelToolStripMenuItem.Text = "Excel";
excelToolStripMenuItem.Click += excelToolStripMenuItem_Click;
//
// pdfToolStripMenuItem
//
pdfToolStripMenuItem.Name = "pdfToolStripMenuItem";
pdfToolStripMenuItem.Size = new Size(224, 26);
pdfToolStripMenuItem.Text = "Pdf";
pdfToolStripMenuItem.Click += pdfToolStripMenuItem_Click;
//
// controlDataListRow1
//
controlDataListRow1.Location = new Point(-4, -2);
controlDataListRow1.Margin = new Padding(4, 5, 4, 5);
controlDataListRow1.Name = "controlDataListRow1";
controlDataListRow1.SelectedRowIndex = -1;
controlDataListRow1.Size = new Size(808, 432);
controlDataListRow1.TabIndex = 1;
//
// FormMain
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 426);
Controls.Add(controlDataListRow1);
Name = "FormMain";
Text = "FormMain";
contextMenuStrip.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private ContextMenuStrip contextMenuStrip;
private ToolStripMenuItem заказToolStripMenuItem;
private ToolStripMenuItem созToolStripMenuItem;
private ToolStripMenuItem редактироватьToolStripMenuItem;
private ToolStripMenuItem удалитьToolStripMenuItem;
private ToolStripMenuItem блюдоToolStripMenuItem;
private ToolStripMenuItem документыToolStripMenuItem;
private ToolStripMenuItem wordToolStripMenuItem;
private ToolStripMenuItem excelToolStripMenuItem;
private ToolStripMenuItem pdfToolStripMenuItem;
private Components.NonVisualComponents.TableComponent tableComponent;
private Components.Components.NonVisualComponents.PdfImage pdfImage;
private ComponentsLibraryNet60.DocumentWithChart.ComponentDocumentWithChartBarWord componentDocumentWithChartBarWord;
private ControlsLibraryNet60.Data.ControlDataListRow controlDataListRow1;
}
}

334
TestForm/FormMain.cs Normal file
View File

@ -0,0 +1,334 @@
using Components.Components.NonVisualComponents.HelperModels;
using Components.Components.VisualComponents;
using Components.NonVisualComponents;
using Components.NonVisualComponents.HelperModels;
using ComponentsLibraryNet60.Models;
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
using Contracts.ViewModels;
using DocumentFormat.OpenXml.Spreadsheet;
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 MergeCells = Components.NonVisualComponents.HelperModels.MergeCells;
namespace WinForms
{
public partial class FormMain : Form
{
private readonly IOrderLogic _orderLogic;
private readonly IDishLogic _dishLogic;
public FormMain(IDishLogic dishLogic, IOrderLogic orderLogic)
{
_dishLogic = dishLogic;
_orderLogic = orderLogic;
InitializeComponent();
controlDataListRow1.ContextMenuStrip = contextMenuStrip;
}
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
try
{
var orders = _orderLogic.ReadList(null);
if (orders == null)
{
return;
}
foreach (var order in orders)
{
controlDataListRow1.AddRow(order);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void AddElement()
{
var service = Program.ServiceProvider?.GetService(typeof(FormOrder));
if (!(service is FormOrder form))
{
return;
}
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
private void UpdateElement()
{
var service = Program.ServiceProvider?.GetService(typeof(FormOrder));
if (!(service is FormOrder form))
{
return;
}
var selectedOrder = controlDataListRow1.GetSelectedObject<OrderViewModel>();
if (selectedOrder == null)
{
MessageBox.Show("Выберите счет для редактирования!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
form.Id = Convert.ToInt32(selectedOrder.Id);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
private void DeleteElement()
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
{
return;
}
var selectedOrder = controlDataListRow1.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();
}
private void CreatePdf()
{
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);
}
else return;
}
List<string> images = new List<string>();
var list = _orderLogic.ReadList(null);
try
{
if (list != null)
{
foreach (var item in list)
{
images.Add(item.PicturePath);
}
string[] imagesArray = images.ToArray();
pdfImage.CreatePdfDoc(new DataForImage(fileName, "Сканы чеков", imagesArray));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка");
}
}
private void CreateExcel()
{
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);
}
else return;
}
string title = "Документ с таблицей";
List<MergeCells> mergeCells = new List<MergeCells>()
{
new MergeCells("Счет", new int[] { 2, 3})
};
List<ColumnInfo> columns = new List<ColumnInfo>()
{
new ColumnInfo("Id", "Идент.", 10),
new ColumnInfo("WaiterFullName", "Статус", 10),
new ColumnInfo("Dish", "Блюдо", 20),
new ColumnInfo("OrderDate", "Дата оплаты чека", 30),
};
var list = _orderLogic.ReadList(null);
try
{
tableComponent.CreateDocument(fileName, title,
mergeCells, columns,
list);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка");
}
}
private void CreateWord()
{
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
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);
}
else return;
}
var items = new Dictionary<string, List<(int Date, double Value)>>();
var list_order = _orderLogic.ReadList(null);
var list_dish = _dishLogic.ReadList(null);
foreach (var dish in list_dish)
{
int count = 0;
foreach (var o in list_order)
if (o.Dish.Contains(dish.Name)) count++;
items.Add(dish.Name, new List<(int Date, double Value)> { (0, count) });
}
try
{
componentDocumentWithChartBarWord.CreateDoc(new ComponentDocumentWithChartConfig
{
FilePath = fileName,
ChartTitle = "Количество заказов определенных блюд",
Data = items
});
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка");
}
}
private void созToolStripMenuItem_Click(object sender, EventArgs e)
{
AddElement();
}
private void редактироватьToolStripMenuItem_Click(object sender, EventArgs e)
{
UpdateElement();
}
private void удалитьToolStripMenuItem_Click(object sender, EventArgs e)
{
DeleteElement();
}
private void wordToolStripMenuItem_Click(object sender, EventArgs e)
{
CreateWord();
}
private void excelToolStripMenuItem_Click(object sender, EventArgs e)
{
CreateExcel();
}
private void pdfToolStripMenuItem_Click(object sender, EventArgs e)
{
CreatePdf();
}
private void ShowFormDish()
{
var service = Program.ServiceProvider?.GetService(typeof(FormDish));
if (!(service is FormDish form))
{
return;
}
form.ShowDialog();
}
private void блюдоToolStripMenuItem_Click(object sender, EventArgs e)
{
ShowFormDish();
}
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))
{
CreateWord();
return true;
}
// Ctrl+T - создать документ Excel
if (keyData == (Keys.Control | Keys.T))
{
CreateExcel();
return true;
}
// Ctrl+C - создать документ Pdf
if (keyData == (Keys.Control | Keys.C))
{
CreatePdf();
return true;
}
// Ctrl+M - вывести форму списка блюд
if (keyData == (Keys.Control | Keys.M))
{
ShowFormDish();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
}

132
TestForm/FormMain.resx Normal file
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="tableComponent.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>194, 17</value>
</metadata>
<metadata name="pdfImage.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>362, 17</value>
</metadata>
<metadata name="componentDocumentWithChartBarWord.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>483, 17</value>
</metadata>
</root>

157
TestForm/FormOrder.Designer.cs generated Normal file
View File

@ -0,0 +1,157 @@
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();
label1 = new Label();
labelDish = new Label();
customTextBox1 = new Components.VisualComponents.CustomTextBox();
textBoxScan = new TextBox();
label2 = new Label();
controlSelectedListBoxSingle = new ControlsLibraryNet60.Selected.ControlSelectedListBoxSingle();
SuspendLayout();
//
// textBoxWaiterFullName
//
textBoxWaiterFullName.Location = new Point(13, 33);
textBoxWaiterFullName.Margin = new Padding(3, 4, 3, 4);
textBoxWaiterFullName.Name = "textBoxWaiterFullName";
textBoxWaiterFullName.Size = new Size(250, 27);
textBoxWaiterFullName.TabIndex = 0;
//
// buttonSave
//
buttonSave.Location = new Point(13, 545);
buttonSave.Margin = new Padding(3, 4, 3, 4);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(114, 31);
buttonSave.TabIndex = 1;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
//
// buttonCancel
//
buttonCancel.Location = new Point(177, 545);
buttonCancel.Margin = new Padding(3, 4, 3, 4);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(86, 31);
buttonCancel.TabIndex = 2;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(13, 9);
label1.Name = "label1";
label1.Size = new Size(129, 20);
label1.TabIndex = 6;
label1.Text = "ФИО официанта*";
//
// labelDish
//
labelDish.AutoSize = true;
labelDish.Location = new Point(13, 117);
labelDish.Name = "labelDish";
labelDish.Size = new Size(146, 20);
labelDish.TabIndex = 7;
labelDish.Text = "Заказанное блюдо*";
//
// customTextBox1
//
customTextBox1.DatePattern = null;
customTextBox1.Location = new Point(13, 401);
customTextBox1.Margin = new Padding(3, 4, 3, 4);
customTextBox1.Name = "customTextBox1";
customTextBox1.Size = new Size(242, 89);
customTextBox1.TabIndex = 9;
//
// textBoxScan
//
textBoxScan.Location = new Point(13, 87);
textBoxScan.Name = "textBoxScan";
textBoxScan.Size = new Size(125, 27);
textBoxScan.TabIndex = 10;
textBoxScan.Text = "Нажми сюда";
textBoxScan.Click += textBoxScan_Click;
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(13, 64);
label2.Name = "label2";
label2.Size = new Size(77, 20);
label2.TabIndex = 12;
label2.Text = "Скан чека";
//
// controlSelectedListBoxSingle
//
controlSelectedListBoxSingle.Location = new Point(13, 142);
controlSelectedListBoxSingle.Margin = new Padding(4, 5, 4, 5);
controlSelectedListBoxSingle.Name = "controlSelectedListBoxSingle";
controlSelectedListBoxSingle.SelectedElement = "";
controlSelectedListBoxSingle.Size = new Size(250, 233);
controlSelectedListBoxSingle.TabIndex = 13;
//
// FormOrder
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(275, 589);
Controls.Add(controlSelectedListBoxSingle);
Controls.Add(label2);
Controls.Add(textBoxScan);
Controls.Add(customTextBox1);
Controls.Add(labelDish);
Controls.Add(label1);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(textBoxWaiterFullName);
Margin = new Padding(3, 4, 3, 4);
Name = "FormOrder";
Text = "Счет";
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBoxWaiterFullName;
private Button buttonSave;
private Button buttonCancel;
private Label label1;
private Label labelDish;
private Components.VisualComponents.CustomTextBox customTextBox1;
private TextBox textBoxScan;
private Label label2;
private ControlsLibraryNet60.Selected.ControlSelectedListBoxSingle controlSelectedListBoxSingle;
}
}

156
TestForm/FormOrder.cs Normal file
View File

@ -0,0 +1,156 @@
using Components.VisualComponents;
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
using Contracts.SearchModels;
using ControlsLibraryNet60.Input;
using DocumentFormat.OpenXml.Office2010.Word.DrawingShape;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinForms
{
public partial class FormOrder : Form
{
private readonly IOrderLogic _orderLogic;
private readonly IDishLogic _dishLogic;
private int? _id;
public int Id { set { _id = value; } }
public FormOrder(IOrderLogic orderLogic, IDishLogic dishLogic)
{
InitializeComponent();
_orderLogic = orderLogic;
_dishLogic = dishLogic;
}
/// <summary>
/// Загрузка формы
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormOrder_Load(object sender, EventArgs e)
{
var listDish = _dishLogic.ReadList(null);
if (listDish != null)
{
foreach (var type in listDish)
{
controlSelectedListBoxSingle.AddElement(type.Name);
}
}
if (!_id.HasValue)
{
return;
}
try
{
var order = _orderLogic.ReadElement(new OrderSearchModel { Id = _id.Value });
if (order == null)
{
return;
}
textBoxWaiterFullName.Text = order.WaiterFullName;
controlSelectedListBoxSingle.SelectedElement = order.Dish;
textBoxScan.Text = order.PicturePath;
customTextBox1.TextBoxValue = order.OrderDate.ToString("dd MMMM yyyy", CultureInfo.CreateSpecificCulture("ru-RU"));
}
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(textBoxScan.Text))
{
MessageBox.Show("Приложите скан чека!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(controlSelectedListBoxSingle.SelectedElement))
{
MessageBox.Show("Выберите блюдо!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(customTextBox1.TextBoxValue))
{
MessageBox.Show("Введите дату заказа!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
var model = new OrderBindingModel
{
Id = _id ?? 0,
WaiterFullName = textBoxWaiterFullName.Text,
Dish = controlSelectedListBoxSingle.SelectedElement,
PicturePath = textBoxScan.Text,
OrderDate = DateTime.Parse(customTextBox1.TextBoxValue),
};
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();
}
private void textBoxScan_Click(object sender, EventArgs e)
{
using (var dialog = new OpenFileDialog { Filter = "jpg|*.jpg" })
{
if (dialog.ShowDialog() == DialogResult.OK)
{
textBoxScan.Text = dialog.FileName.ToString();
}
}
}
}
}

120
TestForm/FormOrder.resx Normal file
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>

64
TestForm/Program.cs Normal file
View File

@ -0,0 +1,64 @@
using BusinessLogics.BusinessLogics;
using Contracts.BusinessLogicsContracts;
using Contracts.StorageContracts;
using DatabaseImplement.Implements;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using WinForms;
namespace TestForm
{
internal static class Program
{
private static ServiceProvider? _serviceProvider;
/// <summary>
/// IoC-êîíòåéíåð
/// </summary>
public static ServiceProvider? ServiceProvider => _serviceProvider;
/// <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();
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<IDishStorage, DishStorage>();
// IoC-êîíòåéíåð, áèçíåñ-ëîãèêà
services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<IDishLogic, DishLogic>();
// IoC-êîíòåéíåð, ôîðìû îòîáðàæåíèÿ
services.AddTransient<FormMain>();
services.AddTransient<FormOrder>();
services.AddTransient<FormDish>();
}
}
}

46
TestForm/TestForm.csproj Normal file
View File

@ -0,0 +1,46 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<None Remove="nlog.config" />
</ItemGroup>
<ItemGroup>
<Content Include="nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="ComponentsLibraryNet60" Version="1.0.0" />
<PackageReference Include="ControlsLibraryNet60" Version="1.0.0" />
<PackageReference Include="CustomComponents" 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.14" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BusinessLogics\BusinessLogics.csproj" />
<ProjectReference Include="..\Components\Components.csproj" />
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\DatabaseImplement\DatabaseImplement.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="packages\" />
</ItemGroup>
</Project>

15
TestForm/nlog.config Normal file
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>

69
WinForms/FormDish.Designer.cs generated Normal file
View File

@ -0,0 +1,69 @@
using System.Windows.Forms;
namespace WinForms
{
partial class FormDish
{
/// <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;
//
// FormDish
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(384, 211);
Controls.Add(dataGridView);
Name = "FormDish";
Text = "Блюда";
Load += FormDish_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
}
}

127
WinForms/FormDish.cs Normal file
View File

@ -0,0 +1,127 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
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
{
public partial class FormDish : Form
{
private readonly IDishLogic _dishLogic;
private BindingList<DishBindingModel> _bindingList;
public FormDish(IDishLogic dishLogic)
{
InitializeComponent();
_dishLogic = dishLogic;
_bindingList = new BindingList<DishBindingModel>();
}
private void FormDish_Load(object sender, EventArgs e)
{
LoadData();
}
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 DishBindingModel
{
Id = id,
Name = name
};
var operatingResult = id != 0 ? _dishLogic.Update(model) : _dishLogic.Create(model);
if (!operatingResult)
{
throw new Exception("Ошибка при создании сущности 'Заказанное блюдо'!");
}
}
else
{
MessageBox.Show("Введена пустая строка!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
LoadData();
}
private void dataGridView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Insert)
{
if (dataGridView.Rows.Count == 0)
{
_bindingList.Add(new DishBindingModel());
dataGridView.DataSource = new BindingList<DishBindingModel>(_bindingList);
dataGridView.CurrentCell = dataGridView.Rows[0].Cells[1];
return;
}
if (dataGridView.Rows[dataGridView.Rows.Count - 1].Cells[1].Value != null)
{
_bindingList.Add(new DishBindingModel());
dataGridView.DataSource = new BindingList<DishBindingModel>(_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)
{
_dishLogic.Delete(new DishBindingModel { Id = (int)dataGridView.CurrentRow.Cells[0].Value });
LoadData();
}
}
}
private void LoadData()
{
try
{
var types = _dishLogic.ReadList(null);
if (types == null)
{
return;
}
_bindingList.Clear();
foreach (var type in types)
{
_bindingList.Add(new DishBindingModel
{
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);
}
}
}
}

120
WinForms/FormDish.resx Normal file
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>

159
WinForms/FormMain.Designer.cs generated Normal file
View File

@ -0,0 +1,159 @@
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);
заказToolStripMenuItem = new ToolStripMenuItem();
созToolStripMenuItem = new ToolStripMenuItem();
редактироватьToolStripMenuItem = new ToolStripMenuItem();
удалитьToolStripMenuItem = new ToolStripMenuItem();
блюдоToolStripMenuItem = new ToolStripMenuItem();
документыToolStripMenuItem = new ToolStripMenuItem();
wordToolStripMenuItem = new ToolStripMenuItem();
excelToolStripMenuItem = new ToolStripMenuItem();
pdfToolStripMenuItem = new ToolStripMenuItem();
tableComponent = new Components.NonVisualComponents.TableComponent(components);
pdfImage = new Components.Components.NonVisualComponents.PdfImage(components);
componentDocumentWithChartBarWord = new ComponentsLibraryNet60.DocumentWithChart.ComponentDocumentWithChartBarWord(components);
controlDataTableRow1 = new ControlsLibraryNet60.Data.ControlDataTableRow();
contextMenuStrip.SuspendLayout();
SuspendLayout();
//
// contextMenuStrip
//
contextMenuStrip.ImageScalingSize = new Size(20, 20);
contextMenuStrip.Items.AddRange(new ToolStripItem[] { заказToolStripMenuItem, блюдоToolStripMenuItem, документыToolStripMenuItem });
contextMenuStrip.Name = "contextMenuStrip";
contextMenuStrip.Size = new Size(157, 76);
contextMenuStrip.Text = "Управление";
//
// заказToolStripMenuItem
//
заказToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { созToolStripMenuItem, редактироватьToolStripMenuItem, удалитьToolStripMenuItem });
заказToolStripMenuItem.Name = аказToolStripMenuItem";
заказToolStripMenuItem.Size = new Size(156, 24);
заказToolStripMenuItem.Text = "Заказ";
//
// созToolStripMenuItem
//
созToolStripMenuItem.Name = "созToolStripMenuItem";
созToolStripMenuItem.Size = new Size(194, 26);
созToolStripMenuItem.Text = "Создать";
созToolStripMenuItem.Click += созToolStripMenuItem_Click;
//
// редактироватьToolStripMenuItem
//
редактироватьToolStripMenuItem.Name = "редактироватьToolStripMenuItem";
редактироватьToolStripMenuItem.Size = new Size(194, 26);
редактироватьToolStripMenuItem.Text = "Редактировать";
редактироватьToolStripMenuItem.Click += редактироватьToolStripMenuItem_Click;
//
// удалитьToolStripMenuItem
//
удалитьToolStripMenuItem.Name = "удалитьToolStripMenuItem";
удалитьToolStripMenuItem.Size = new Size(194, 26);
удалитьToolStripMenuItem.Text = "Удалить";
удалитьToolStripMenuItem.Click += удалитьToolStripMenuItem_Click;
//
// блюдоToolStripMenuItem
//
блюдоToolStripMenuItem.Name = "блюдоToolStripMenuItem";
блюдоToolStripMenuItem.Size = new Size(156, 24);
блюдоToolStripMenuItem.Text = "Блюдо";
блюдоToolStripMenuItem.Click += блюдоToolStripMenuItem_Click;
//
// документыToolStripMenuItem
//
документыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { wordToolStripMenuItem, excelToolStripMenuItem, pdfToolStripMenuItem });
документыToolStripMenuItem.Name = окументыToolStripMenuItem";
документыToolStripMenuItem.Size = new Size(156, 24);
документыToolStripMenuItem.Text = "Документы";
//
// wordToolStripMenuItem
//
wordToolStripMenuItem.Name = "wordToolStripMenuItem";
wordToolStripMenuItem.Size = new Size(128, 26);
wordToolStripMenuItem.Text = "Word";
wordToolStripMenuItem.Click += wordToolStripMenuItem_Click;
//
// excelToolStripMenuItem
//
excelToolStripMenuItem.Name = "excelToolStripMenuItem";
excelToolStripMenuItem.Size = new Size(128, 26);
excelToolStripMenuItem.Text = "Excel";
excelToolStripMenuItem.Click += excelToolStripMenuItem_Click;
//
// pdfToolStripMenuItem
//
pdfToolStripMenuItem.Name = "pdfToolStripMenuItem";
pdfToolStripMenuItem.Size = new Size(128, 26);
pdfToolStripMenuItem.Text = "Pdf";
pdfToolStripMenuItem.Click += pdfToolStripMenuItem_Click;
//
// controlDataTableRow1
//
controlDataTableRow1.Dock = DockStyle.Fill;
controlDataTableRow1.Location = new Point(0, 0);
controlDataTableRow1.Margin = new Padding(4, 5, 4, 5);
controlDataTableRow1.Name = "controlDataTableRow1";
controlDataTableRow1.SelectedRowIndex = -1;
controlDataTableRow1.Size = new Size(800, 426);
controlDataTableRow1.TabIndex = 1;
//
// FormMain
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 426);
Controls.Add(controlDataTableRow1);
Name = "FormMain";
Text = "FormMain";
Load += FormMain_Load;
contextMenuStrip.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private ContextMenuStrip contextMenuStrip;
private ToolStripMenuItem заказToolStripMenuItem;
private ToolStripMenuItem созToolStripMenuItem;
private ToolStripMenuItem редактироватьToolStripMenuItem;
private ToolStripMenuItem удалитьToolStripMenuItem;
private ToolStripMenuItem блюдоToolStripMenuItem;
private ToolStripMenuItem документыToolStripMenuItem;
private ToolStripMenuItem wordToolStripMenuItem;
private ToolStripMenuItem excelToolStripMenuItem;
private ToolStripMenuItem pdfToolStripMenuItem;
private Components.NonVisualComponents.TableComponent tableComponent;
private Components.Components.NonVisualComponents.PdfImage pdfImage;
private ComponentsLibraryNet60.DocumentWithChart.ComponentDocumentWithChartBarWord componentDocumentWithChartBarWord;
private ControlsLibraryNet60.Data.ControlDataTableRow controlDataTableRow1;
}
}

386
WinForms/FormMain.cs Normal file
View File

@ -0,0 +1,386 @@
using BusinessLogics.BusinessLogics;
using Components.Components.NonVisualComponents.HelperModels;
using Components.Components.VisualComponents;
using Components.NonVisualComponents;
using Components.NonVisualComponents.HelperModels;
using ComponentsLibraryNet60.DocumentWithChart;
using ComponentsLibraryNet60.Models;
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
using Contracts.ViewModels;
using ControlsLibraryNet60.Models;
using DocumentFormat.OpenXml.Spreadsheet;
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 MergeCells = Components.NonVisualComponents.HelperModels.MergeCells;
namespace WinForms
{
public partial class FormMain : Form
{
private readonly IOrderLogic _orderLogic;
private readonly IDishLogic _dishLogic;
public FormMain(IDishLogic dishLogic, IOrderLogic orderLogic)
{
_dishLogic = dishLogic;
_orderLogic = orderLogic;
InitializeComponent();
List<DataTableColumnConfig> columnConfigs = new List<DataTableColumnConfig>
{
new DataTableColumnConfig
{
ColumnHeader = "Идентификатор",
PropertyName = "Id",
Width = 150,
Visible = true
},
new DataTableColumnConfig
{
ColumnHeader = "ФИО официанта",
PropertyName = "WaiterFullName",
Width = 250,
Visible = true
},
new DataTableColumnConfig
{
ColumnHeader = "Заказанное блюдо",
PropertyName = "Dish",
Width = 200,
Visible = true
},
new DataTableColumnConfig
{
ColumnHeader = "Дата оплаты счета",
PropertyName = "OrderDate",
Width = 200,
Visible = true
}
};
controlDataTableRow1.LoadColumns(columnConfigs);
controlDataTableRow1.ContextMenuStrip = contextMenuStrip;
}
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
controlDataTableRow1.Clear();
try
{
var orders = _orderLogic.ReadList(null);
if (orders == null)
{
return;
}
foreach (var order in orders)
{
controlDataTableRow1.AddRow(order);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void AddElement()
{
var service = Program.ServiceProvider?.GetService(typeof(FormOrder));
if (!(service is FormOrder form))
{
return;
}
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
private void UpdateElement()
{
var service = Program.ServiceProvider?.GetService(typeof(FormOrder));
if (!(service is FormOrder form))
{
return;
}
var selectedOrder = controlDataTableRow1.GetSelectedObject<OrderViewModel>();
if (selectedOrder == null)
{
MessageBox.Show("Выберите счет для редактирования!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
form.Id = Convert.ToInt32(selectedOrder.Id);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
private void DeleteElement()
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
{
return;
}
var selectedOrder = controlDataTableRow1.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();
}
private void CreatePdf()
{
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);
}
else return;
}
List<string> images = new List<string>();
var list = _orderLogic.ReadList(null);
try
{
if (list != null)
{
foreach (var item in list)
{
images.Add(item.PicturePath);
}
string[] imagesArray = images.ToArray();
pdfImage.CreatePdfDoc(new DataForImage(fileName, "Сканы чеков", imagesArray));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка");
}
}
private void CreateExcel()
{
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);
}
else return;
}
string title = "Документ с таблицей";
List<MergeCells> mergeCells = new List<MergeCells>()
{
new MergeCells("Счет", new int[] { 1, 2})
};
List<ColumnInfo> columns = new List<ColumnInfo>()
{
new ColumnInfo("Id", "Идент.", 10),
new ColumnInfo("WaiterFullName", "ФИО официанта", 20),
new ColumnInfo("Dish", "Блюдо", 20),
new ColumnInfo("OrderDate", "Дата оплаты чека", 30),
new ColumnInfo("", "заглушка", 0),
};
var list = _orderLogic.ReadList(null);
try
{
tableComponent.CreateDocument(fileName, title,
mergeCells, columns,
list);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка");
}
}
private void CreateWord()
{
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
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);
}
else return;
}
var data = new Dictionary<string, List<(int Date, double Value)>>();
var orders = _orderLogic.ReadList(null);
var groupedOrders = orders.GroupBy(order => order.Dish)
.Select(group => new
{
DishName = group.Key,
OrderCount = group.Count()
})
.ToList();
data["Блюда"] = new List<(int Date, double Value)>();
int counter = 1;
foreach (var group in groupedOrders)
{
data["Блюда"].Add((counter, group.OrderCount));
counter++;
}
try
{
componentDocumentWithChartBarWord.CreateDoc(new ComponentDocumentWithChartConfig
{
Header = "test",
FilePath = fileName,
ChartTitle = "Количество заказов определенных блюд",
LegendLocation = ComponentsLibraryNet60.Models.Location.Bottom,
Data = data
});
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка");
}
}
private void созToolStripMenuItem_Click(object sender, EventArgs e)
{
AddElement();
}
private void редактироватьToolStripMenuItem_Click(object sender, EventArgs e)
{
UpdateElement();
}
private void удалитьToolStripMenuItem_Click(object sender, EventArgs e)
{
DeleteElement();
}
private void wordToolStripMenuItem_Click(object sender, EventArgs e)
{
CreateWord();
}
private void excelToolStripMenuItem_Click(object sender, EventArgs e)
{
CreateExcel();
}
private void pdfToolStripMenuItem_Click(object sender, EventArgs e)
{
CreatePdf();
}
private void ShowFormDish()
{
var service = Program.ServiceProvider?.GetService(typeof(FormDish));
if (!(service is FormDish form))
{
return;
}
form.ShowDialog();
}
private void блюдоToolStripMenuItem_Click(object sender, EventArgs e)
{
ShowFormDish();
}
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))
{
CreateWord();
return true;
}
// Ctrl+T - создать документ Excel
if (keyData == (Keys.Control | Keys.T))
{
CreateExcel();
return true;
}
// Ctrl+C - создать документ Pdf
if (keyData == (Keys.Control | Keys.C))
{
CreatePdf();
return true;
}
// Ctrl+M - вывести форму списка блюд
if (keyData == (Keys.Control | Keys.M))
{
ShowFormDish();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
}

135
WinForms/FormMain.resx Normal file
View File

@ -0,0 +1,135 @@
<?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="tableComponent.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>194, 17</value>
</metadata>
<metadata name="pdfImage.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>362, 17</value>
</metadata>
<metadata name="componentDocumentWithChartBarWord.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>483, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>67</value>
</metadata>
</root>

160
WinForms/FormOrder.Designer.cs generated Normal file
View File

@ -0,0 +1,160 @@
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();
label1 = new Label();
labelDish = new Label();
customTextBox1 = new Components.VisualComponents.CustomTextBox();
textBoxScan = new TextBox();
label2 = new Label();
controlSelectedListBoxSingle = new ControlsLibraryNet60.Selected.ControlSelectedListBoxSingle();
SuspendLayout();
//
// textBoxWaiterFullName
//
textBoxWaiterFullName.Location = new Point(13, 33);
textBoxWaiterFullName.Margin = new Padding(3, 4, 3, 4);
textBoxWaiterFullName.Name = "textBoxWaiterFullName";
textBoxWaiterFullName.Size = new Size(250, 27);
textBoxWaiterFullName.TabIndex = 0;
//
// buttonSave
//
buttonSave.Location = new Point(13, 545);
buttonSave.Margin = new Padding(3, 4, 3, 4);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(114, 31);
buttonSave.TabIndex = 1;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(177, 545);
buttonCancel.Margin = new Padding(3, 4, 3, 4);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(86, 31);
buttonCancel.TabIndex = 2;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(13, 9);
label1.Name = "label1";
label1.Size = new Size(129, 20);
label1.TabIndex = 6;
label1.Text = "ФИО официанта*";
//
// labelDish
//
labelDish.AutoSize = true;
labelDish.Location = new Point(13, 117);
labelDish.Name = "labelDish";
labelDish.Size = new Size(146, 20);
labelDish.TabIndex = 7;
labelDish.Text = "Заказанное блюдо*";
//
// customTextBox1
//
customTextBox1.DatePattern = null;
customTextBox1.Location = new Point(13, 401);
customTextBox1.Margin = new Padding(3, 4, 3, 4);
customTextBox1.Name = "customTextBox1";
customTextBox1.Size = new Size(242, 89);
customTextBox1.TabIndex = 9;
//
// textBoxScan
//
textBoxScan.Location = new Point(13, 87);
textBoxScan.Name = "textBoxScan";
textBoxScan.Size = new Size(125, 27);
textBoxScan.TabIndex = 10;
textBoxScan.Text = "Нажми сюда";
textBoxScan.Click += textBoxScan_Click;
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(13, 64);
label2.Name = "label2";
label2.Size = new Size(77, 20);
label2.TabIndex = 12;
label2.Text = "Скан чека";
//
// controlSelectedListBoxSingle
//
controlSelectedListBoxSingle.Location = new Point(13, 142);
controlSelectedListBoxSingle.Margin = new Padding(4, 5, 4, 5);
controlSelectedListBoxSingle.Name = "controlSelectedListBoxSingle";
controlSelectedListBoxSingle.SelectedElement = "";
controlSelectedListBoxSingle.Size = new Size(250, 233);
controlSelectedListBoxSingle.TabIndex = 13;
//
// FormOrder
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(275, 589);
Controls.Add(controlSelectedListBoxSingle);
Controls.Add(label2);
Controls.Add(textBoxScan);
Controls.Add(customTextBox1);
Controls.Add(labelDish);
Controls.Add(label1);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(textBoxWaiterFullName);
Margin = new Padding(3, 4, 3, 4);
Name = "FormOrder";
Text = "Счет";
Load += FormOrder_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBoxWaiterFullName;
private Button buttonSave;
private Button buttonCancel;
private Label label1;
private Label labelDish;
private Components.VisualComponents.CustomTextBox customTextBox1;
private TextBox textBoxScan;
private Label label2;
private ControlsLibraryNet60.Selected.ControlSelectedListBoxSingle controlSelectedListBoxSingle;
}
}

160
WinForms/FormOrder.cs Normal file
View File

@ -0,0 +1,160 @@
using Components.VisualComponents;
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
using Contracts.SearchModels;
using ControlsLibraryNet60.Input;
using DocumentFormat.OpenXml.Office2010.Word.DrawingShape;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinForms
{
public partial class FormOrder : Form
{
private readonly IOrderLogic _orderLogic;
private readonly IDishLogic _dishLogic;
private int? _id;
public int Id { set { _id = value; } }
public FormOrder(IOrderLogic orderLogic, IDishLogic dishLogic)
{
InitializeComponent();
_orderLogic = orderLogic;
_dishLogic = dishLogic;
customTextBox1.DatePattern = @"^(\d{2}.\d{2}.\d{4})$";
}
/// <summary>
/// Загрузка формы
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormOrder_Load(object sender, EventArgs e)
{
var listDish = _dishLogic.ReadList(null);
if (listDish != null)
{
foreach (var type in listDish)
{
controlSelectedListBoxSingle.AddElement(type.Name);
}
}
if (!_id.HasValue)
{
return;
}
try
{
var order = _orderLogic.ReadElement(new OrderSearchModel { Id = _id.Value });
if (order == null)
{
return;
}
textBoxWaiterFullName.Text = order.WaiterFullName;
controlSelectedListBoxSingle.SelectedElement = order.Dish;
textBoxScan.Text = order.PicturePath;
customTextBox1.TextBoxValue = order.OrderDate.ToString("dd MM yyyy", CultureInfo.CreateSpecificCulture("ru-RU"));
}
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)
{
customTextBox1.DatePattern = @"^(\d{2}.\d{2}.\d{4})$";
if (string.IsNullOrEmpty(textBoxWaiterFullName.Text))
{
MessageBox.Show("Заполните ФИО официанта!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxScan.Text))
{
MessageBox.Show("Приложите скан чека!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(controlSelectedListBoxSingle.SelectedElement))
{
MessageBox.Show("Выберите блюдо!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(customTextBox1.TextBoxValue))
{
MessageBox.Show("Введите дату заказа!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
var model = new OrderBindingModel
{
Id = _id ?? 0,
WaiterFullName = textBoxWaiterFullName.Text,
Dish = controlSelectedListBoxSingle.SelectedElement,
PicturePath = textBoxScan.Text,
OrderDate = DateTime.Parse(customTextBox1.TextBoxValue).ToUniversalTime(),
};
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();
}
private void textBoxScan_Click(object sender, EventArgs e)
{
using (var dialog = new OpenFileDialog { Filter = "jpg|*.jpg" })
{
if (dialog.ShowDialog() == DialogResult.OK)
{
textBoxScan.Text = dialog.FileName.ToString();
}
}
}
}
}

120
WinForms/FormOrder.resx Normal file
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,306 @@
using Plugins;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComponentsLibraryNet60.Models;
using Contracts.BindingModels;
using Contracts.BusinessLogicsContracts;
using Contracts.ViewModels;
using ControlsLibraryNet60.Models;
using Components.NonVisualComponents.HelperModels;
using Components.Components.NonVisualComponents.HelperModels;
using ControlsLibraryNet60.Data;
using BusinessLogics.BusinessLogics;
using Components.Components.VisualComponents;
using DatabaseImplement.Implements;
using Microsoft.Extensions.Logging;
using System.Windows.Forms;
using NLog.Extensions.Logging;
using Components.NonVisualComponents;
using Components.Components.NonVisualComponents;
using ComponentsLibraryNet60.DocumentWithTable;
using ComponentsLibraryNet60.DocumentWithChart;
namespace WinForms
{
public class PluginsConvention : IPluginsConvention
{
/// <summary>
/// Название плагина
/// </summary>
public string PluginName => "Orders";
private readonly ControlDataTableRow controlDataTableRow1;
private readonly IOrderLogic _orderLogic;
private readonly IDishLogic _dishLogic;
public PluginsConvention()
{
List<DataTableColumnConfig> columnConfigs = new List<DataTableColumnConfig>
{
new DataTableColumnConfig
{
ColumnHeader = "Идентификатор",
PropertyName = "Id",
Width = 150,
Visible = true
},
new DataTableColumnConfig
{
ColumnHeader = "ФИО официанта",
PropertyName = "WaiterFullName",
Width = 250,
Visible = true
},
new DataTableColumnConfig
{
ColumnHeader = "Заказанное блюдо",
PropertyName = "Dish",
Width = 200,
Visible = true
},
new DataTableColumnConfig
{
ColumnHeader = "Дата оплаты счета",
PropertyName = "OrderDate",
Width = 200,
Visible = true
}
};
controlDataTableRow1 = new ControlDataTableRow();
controlDataTableRow1.LoadColumns(columnConfigs);
var loggerFactory = LoggerFactory.Create(builder => builder.AddNLog());
var orderLogicLogger = loggerFactory.CreateLogger<OrderLogic>();
var dishLogicLogger = loggerFactory.CreateLogger<DishLogic>();
_orderLogic = new OrderLogic(orderLogicLogger, new OrderStorage());
_dishLogic = new DishLogic(dishLogicLogger, new DishStorage());
}
public UserControl GetControl
{
get
{
ReloadData();
return controlDataTableRow1;
}
}
public PluginsConventionElement GetElement
{
get
{
var order = controlDataTableRow1.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) };
}
}
public Form GetForm(PluginsConventionElement element)
{
if (element == null)
{
return new FormOrder(_orderLogic, _dishLogic);
}
if (element.Id.GetHashCode() >= 0)
{
byte[] bytes = element.Id.ToByteArray();
int Id = BitConverter.ToInt32(bytes, 0);
var form = new FormOrder(_orderLogic, _dishLogic);
form.Id = Id;
return form;
}
return null;
}
public Form GetThesaurus()
{
return new FormDish(_dishLogic);
}
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;
}
}
public void ReloadData()
{
controlDataTableRow1.Clear();
try
{
var orders = _orderLogic.ReadList(null);
if (orders == null)
{
return;
}
foreach (var order in orders)
{
controlDataTableRow1.AddRow(order);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public bool CreateSimpleDocument(PluginsConventionSaveDocument saveDocument)
{
List<string> images = new List<string>();
var list = _orderLogic.ReadList(null);
try
{
if (list != null)
{
foreach (var item in list)
{
images.Add(item.PicturePath);
}
string[] imagesArray = images.ToArray();
var pdfImage = new PdfImage();
pdfImage.CreatePdfDoc(new DataForImage(saveDocument.FileName, "Сканы чеков", imagesArray));
return true;
}
return false;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка");
return false;
}
}
public bool CreateTableDocument(PluginsConventionSaveDocument saveDocument)
{
string title = "Документ с таблицей";
List<MergeCells> mergeCells = new List<MergeCells>()
{
new MergeCells("Счет", new int[] { 1, 2})
};
List<ColumnInfo> columns = new List<ColumnInfo>()
{
new ColumnInfo("Id", "Идент.", 10),
new ColumnInfo("WaiterFullName", "ФИО официанта", 20),
new ColumnInfo("Dish", "Блюдо", 20),
new ColumnInfo("OrderDate", "Дата оплаты чека", 30),
new ColumnInfo("", "заглушка", 0),
};
var list = _orderLogic.ReadList(null);
if (list == null)
{
return false;
}
var tableComponent = new TableComponent();
try
{
tableComponent.CreateDocument(saveDocument.FileName, title,
mergeCells, columns,
list);
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка");
return false;
}
}
public bool CreateChartDocument(PluginsConventionSaveDocument saveDocument)
{
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
var data = new Dictionary<string, List<(int Date, double Value)>>();
var orders = _orderLogic.ReadList(null);
if (orders == null)
{
return false;
}
var groupedOrders = orders.GroupBy(order => order.Dish)
.Select(group => new
{
DishName = group.Key,
OrderCount = group.Count()
})
.ToList();
data["Блюда"] = new List<(int Date, double Value)>();
int counter = 1;
foreach (var group in groupedOrders)
{
data["Блюда"].Add((counter, group.OrderCount));
counter++;
}
var componentDocumentWithChartBarWord = new ComponentDocumentWithChartBarWord();
try
{
componentDocumentWithChartBarWord.CreateDoc(new ComponentDocumentWithChartConfig
{
Header = "test",
FilePath = saveDocument.FileName,
ChartTitle = "Количество заказов определенных блюд",
LegendLocation = ComponentsLibraryNet60.Models.Location.Bottom,
Data = data
});
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка");
return false;
}
}
}
}

63
WinForms/Program.cs Normal file
View File

@ -0,0 +1,63 @@
using BusinessLogics.BusinessLogics;
using Contracts.BusinessLogicsContracts;
using Contracts.StorageContracts;
using DatabaseImplement.Implements;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
namespace WinForms
{
internal static class Program
{
private static ServiceProvider? _serviceProvider;
/// <summary>
/// IoC-контейнер
/// </summary>
public static ServiceProvider? ServiceProvider => _serviceProvider;
/// <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();
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<IDishStorage, DishStorage>();
// IoC-контейнер, бизнес-логика
services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<IDishLogic, DishLogic>();
// IoC-контейнер, формы отображения
services.AddTransient<FormMain>();
services.AddTransient<FormOrder>();
services.AddTransient<FormDish>();
}
}
}

48
WinForms/WinForms.csproj Normal file
View File

@ -0,0 +1,48 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<OutputType>WinExe</OutputType>
</PropertyGroup>
<ItemGroup>
<None Remove="nlog.config" />
</ItemGroup>
<ItemGroup>
<Content Include="nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="ComponentsLibraryNet60" Version="1.0.0" />
<PackageReference Include="ControlsLibraryNet60" Version="1.0.0" />
<PackageReference Include="CustomComponents" 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.14" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BusinessLogics\BusinessLogics.csproj" />
<ProjectReference Include="..\Components\Components.csproj" />
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\DatabaseImplement\DatabaseImplement.csproj" />
<ProjectReference Include="..\Plugins\Plugins.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="packages\" />
</ItemGroup>
</Project>

15
WinForms/nlog.config Normal file
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>

184
WinFormsPlugin/FormMain.Designer.cs generated Normal file
View File

@ -0,0 +1,184 @@
namespace WinFormsPlugin
{
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;
}
}

307
WinFormsPlugin/FormMain.cs Normal file
View File

@ -0,0 +1,307 @@
using Plugins;
using System.Reflection;
namespace WinFormsPlugin
{
/// <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)
{
// Îøèáêà ïðè çàãðóçêå ïëàãèíà
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 = "pdf|*.pdf" })
{
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 = "xlsx|*.xlsx" })
{
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 = "docx|*.docx" })
{
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();
}
}

17
WinFormsPlugin/Program.cs Normal file
View File

@ -0,0 +1,17 @@
namespace WinFormsPlugin
{
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,18 @@
<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>
</Project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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