Lab3 is done

This commit is contained in:
DyCTaTOR 2024-11-11 22:20:20 +04:00
parent 40971f2997
commit f5a1ac2240
31 changed files with 1584 additions and 16 deletions

View File

@ -0,0 +1,69 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicContracts;
using Contracts.SearchModels;
using Contracts.StorageContracts;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLogics.BusinessLogics
{
public class CategoryLogic : ICategoryLogic
{
private readonly ICategoryStorage _categoryStorage;
public CategoryLogic(ICategoryStorage categoryStorage)
{
_categoryStorage = categoryStorage;
}
public List<CategoryViewModel> ReadList()
{
return _categoryStorage.GetFullList();
}
public bool Create(CategoryBindingModel model)
{
CheckModel(model);
if (_categoryStorage.Insert(model) == null)
{
return false;
}
return true;
}
public bool Update(CategoryBindingModel model)
{
CheckModel(model);
if (_categoryStorage.Update(model) == null)
{
return false;
}
return true;
}
public bool Delete(CategoryBindingModel model)
{
CheckModel(model, false);
if (_categoryStorage.Delete(model) == null)
{
return false;
}
return true;
}
private void CheckModel(CategoryBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
}
}
}

View File

@ -0,0 +1,15 @@
using Models.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.BindingModels
{
public class CategoryBindingModel : ICategoryModel
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
}
}

View File

@ -13,7 +13,7 @@ namespace Contracts.BindingModels
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public Category Category { get; set; }
public string Category { get; set; } = string.Empty;
public int CountOnStorage { get; set; }
}
}

View File

@ -0,0 +1,19 @@
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.BusinessLogicContracts
{
public interface ICategoryLogic
{
List<CategoryViewModel>? ReadList();
bool Create(CategoryBindingModel model);
bool Update(CategoryBindingModel model);
bool Delete(CategoryBindingModel model);
}
}

View File

@ -1,4 +1,5 @@
using Models.Enums;
using Models.Models;
using System;
using System.Collections.Generic;
using System.Linq;
@ -11,6 +12,6 @@ namespace Contracts.SearchModels
{
public int? Id { get; set; }
public string? Name { get; set; }
public Category? Category { get; set; }
public string? Category { get; set; }
}
}

View File

@ -0,0 +1,19 @@
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 ICategoryStorage
{
List<CategoryViewModel> GetFullList();
CategoryViewModel? Insert(CategoryBindingModel model);
CategoryViewModel? Update(CategoryBindingModel model);
CategoryViewModel? Delete(CategoryBindingModel model);
}
}

View File

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

View File

@ -17,7 +17,7 @@ namespace Contracts.ViewModels
[DisplayName("Описание")]
public string Description { get; set; } = string.Empty;
[DisplayName("Категория продукта")]
public Category Category { get; set; }
public string Category { get; set; } = string.Empty;
[DisplayName("Количество товаров на складе")]
public int CountOnStorage { get; set; }
}

View File

@ -6,6 +6,7 @@ namespace DatabaseImplement
public class Database : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<Category> Categories { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{

View File

@ -0,0 +1,51 @@
using Contracts.BindingModels;
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 CategoryStorage : ICategoryStorage
{
public List<CategoryViewModel> GetFullList()
{
using var context = new Database();
return context.Categories.Select(x => x.GetViewModel).ToList();
}
public CategoryViewModel? Insert(CategoryBindingModel model)
{
var newProvider = Category.Create(model);
if (newProvider == null) return null;
using var context = new Database();
context.Categories.Add(newProvider);
context.SaveChanges();
return newProvider.GetViewModel;
}
public CategoryViewModel? Update(CategoryBindingModel model)
{
using var context = new Database();
var provider = context.Categories.FirstOrDefault(x => x.Id == model.Id);
if (provider == null) return null;
provider.Update(model);
context.SaveChanges();
return provider.GetViewModel;
}
public CategoryViewModel? Delete(CategoryBindingModel model)
{
using var context = new Database();
var element = context.Categories.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
context.Categories.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,74 @@
// <auto-generated />
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("20241111151239_AddCategories")]
partial class AddCategories
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("DatabaseImplement.Models.Category", 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("Categories");
});
modelBuilder.Entity("DatabaseImplement.Models.Product", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Category")
.IsRequired()
.HasColumnType("text");
b.Property<int>("CountOnStorage")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Products");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,51 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace DatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class AddCategories : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Category",
table: "Products",
type: "text",
nullable: false,
oldClrType: typeof(int),
oldType: "integer");
migrationBuilder.CreateTable(
name: "Categories",
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_Categories", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Categories");
migrationBuilder.AlterColumn<int>(
name: "Category",
table: "Products",
type: "integer",
nullable: false,
oldClrType: typeof(string),
oldType: "text");
}
}
}

View File

@ -21,6 +21,23 @@ namespace DatabaseImplement.Migrations
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("DatabaseImplement.Models.Category", 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("Categories");
});
modelBuilder.Entity("DatabaseImplement.Models.Product", b =>
{
b.Property<int>("Id")
@ -29,8 +46,9 @@ namespace DatabaseImplement.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Category")
.HasColumnType("integer");
b.Property<string>("Category")
.IsRequired()
.HasColumnType("text");
b.Property<int>("CountOnStorage")
.HasColumnType("integer");

View File

@ -0,0 +1,40 @@
using Contracts.BindingModels;
using Contracts.ViewModels;
using Models.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement.Models
{
public class Category : ICategoryModel
{
public int Id { get; set; }
public string Name { get; set; }
public static Category? Create(CategoryBindingModel model)
{
if (model == null) return null;
return new Category
{
Id = model.Id,
Name = model.Name,
};
}
public void Update(CategoryBindingModel model)
{
if (model == null) return;
Name = model.Name;
}
public CategoryViewModel GetViewModel => new()
{
Id = Id,
Name = Name,
};
}
}

View File

@ -23,7 +23,7 @@ namespace DatabaseImplement.Models
public string Description { get; private set; } = string.Empty;
[Required]
public Category Category { get; private set; }
public string Category { get; private set; }
[Required]
public int CountOnStorage { get; private set; }

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Models.Models
{
public interface ICategoryModel : IId
{
string Name { get; }
}
}

View File

@ -11,7 +11,7 @@ namespace Models.Models
{
string Name { get;}
string Description { get;}
Category Category { get;}
string Category { get;}
int CountOnStorage { get;}
}
}

View File

@ -0,0 +1,64 @@
namespace Forms
{
partial class CategoryForm
{
/// <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()
{
dataGridViewCategories = new System.Windows.Forms.DataGridView();
((System.ComponentModel.ISupportInitialize)(dataGridViewCategories)).BeginInit();
SuspendLayout();
//
// dataGridViewCategories
//
dataGridViewCategories.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewCategories.Location = new System.Drawing.Point(12, 12);
dataGridViewCategories.Name = "dataGridViewCategories";
dataGridViewCategories.RowHeadersWidth = 51;
dataGridViewCategories.Size = new System.Drawing.Size(711, 426);
dataGridViewCategories.TabIndex = 0;
dataGridViewCategories.CellValueChanged += dataGridViewCategories_CellValueChanged;
dataGridViewCategories.UserAddedRow += dataGridViewCategories_UserAddedRow;
dataGridViewCategories.UserDeletingRow += dataGridViewCategories_UserDeletingRow;
dataGridViewCategories.KeyDown += dataGridViewCategories_KeyDown;
//
// CategoryForm
//
AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
ClientSize = new System.Drawing.Size(731, 450);
Controls.Add(dataGridViewCategories);
Name = "CategoryForm";
Text = "CategoryForm";
((System.ComponentModel.ISupportInitialize)(dataGridViewCategories)).EndInit();
ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView dataGridViewCategories;
}
}

View File

@ -0,0 +1,106 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicContracts;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Forms
{
public partial class CategoryForm : Form
{
private readonly ICategoryLogic _categoryLogic;
public CategoryForm(ICategoryLogic categoryLogic)
{
InitializeComponent();
_categoryLogic = categoryLogic;
LoadCategories();
}
private void LoadCategories()
{
var categories = _categoryLogic.ReadList().ToList();
dataGridViewCategories.DataSource = categories;
}
private void dataGridViewCategories_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0)
{
var category = dataGridViewCategories.Rows[e.RowIndex].DataBoundItem as CategoryViewModel;
if (category != null)
{
var model = new CategoryBindingModel
{
Id = category.Id,
Name = category.Name
};
_categoryLogic.Update(model);
}
}
}
private void dataGridViewCategories_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
{
var category = e.Row.DataBoundItem as CategoryViewModel;
if (category != null)
{
if (MessageBox.Show("Вы уверены, что хотите удалить выбранную категорию?", "Да", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
_categoryLogic.Delete(new CategoryBindingModel { Id = category.Id });
}
else
{
e.Cancel = true;
}
}
}
private void dataGridViewCategories_UserAddedRow(object sender, DataGridViewRowEventArgs e)
{
var category = new CategoryViewModel { Name = "" };
var model = new CategoryBindingModel
{
Name = category.Name
};
_categoryLogic.Create(model);
LoadCategories();
}
private void dataGridViewCategories_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Insert)
{
var category = new CategoryViewModel { Name = "" };
var model = new CategoryBindingModel
{
Name = category.Name
};
_categoryLogic.Create(model);
LoadCategories();
}
else if (e.KeyCode == Keys.Delete)
{
if (dataGridViewCategories.SelectedRows.Count > 0)
{
var selectedCategory = dataGridViewCategories.SelectedRows[0].DataBoundItem as CategoryViewModel;
if (selectedCategory != null)
{
if (MessageBox.Show("Вы уверены, что хотите удалить выбранную категорию?", "Да", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
_categoryLogic.Delete(new CategoryBindingModel { Id = selectedCategory.Id });
LoadCategories();
}
}
}
}
}
}
}

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

@ -22,7 +22,7 @@
<ProjectReference Include="..\Businesslogic\BusinessLogics.csproj" />
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\DatabaseImplement\DatabaseImplement.csproj" />
<ProjectReference Include="..\WinFormsLibrary1\Components.csproj" />
<ProjectReference Include="..\WinFormsLibrary1\WinFormsLibrary1.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,64 @@
namespace Forms
{
partial class MainForm
{
/// <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();
_productListControl = new Library15Gerimovich.OutputTableResults();
wordTablesComponent1 = new Library15Gerimovich.WordTablesComponent(components);
SuspendLayout();
//
// _productListControl
//
_productListControl.Dock = DockStyle.Fill;
_productListControl.Location = new Point(0, 0);
_productListControl.Margin = new Padding(3, 5, 3, 5);
_productListControl.Name = "_productListControl";
_productListControl.SelectedRow = -1;
_productListControl.Size = new Size(487, 335);
_productListControl.TabIndex = 0;
//
// MainForm
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(487, 335);
Controls.Add(_productListControl);
Margin = new Padding(3, 4, 3, 4);
Name = "MainForm";
Text = "Учет продуктов в магазине";
Load += MainForm_Load;
ResumeLayout(false);
}
#endregion
private Library15Gerimovich.OutputTableResults _productListControl;
private Library15Gerimovich.WordTablesComponent wordTablesComponent1;
}
}

View File

@ -0,0 +1,291 @@
using System;
using System.Windows.Forms;
using Contracts.BindingModels;
using Contracts.BusinessLogicContracts;
using Contracts.SearchModels;
using Contracts.ViewModels;
using Library14Petrushin;
using Library14Petrushin.Classes;
using Library15Gerimovich;
using Library15Gerimovich.OfficePackage.HelperModels;
using WinFormsLibrary1;
using WinFormsLibrary1.Models;
using LegendPosition = Library14Petrushin.Classes.LegendPosition;
namespace Forms
{
public partial class MainForm : Form
{
private readonly IProductLogic _productLogic;
private readonly ICategoryLogic _categoryLogic;
private ToolStrip toolStrip;
public MainForm(IProductLogic productLogic, ICategoryLogic categoryLogic)
{
InitializeComponent();
_productLogic = productLogic;
_categoryLogic = categoryLogic;
LoadProducts();
}
private void LoadProducts()
{
var products = _productLogic.ReadList(null);
_productListControl.ClearGrid();
// Создаем список столбцов
var columns = new List<ColumnInfo>
{
new ColumnInfo("ID", 50, false, "Id"),
new ColumnInfo("Название", 150, true, "Name"),
new ColumnInfo("Описание", 200, true, "Description"),
new ColumnInfo("Категория продукта", 150, true, "Category"),
new ColumnInfo("Количество товаров на складе", 150, true, "CountOnStorage")
};
// Настраиваем столбцы в DataGridView
_productListControl.ConfigureColumns(columns);
// Добавляем строки
foreach (var product in products)
{
_productListControl.InsertValue(product);
}
}
private void MainForm_Load(object sender, EventArgs e)
{
// Настройка контекстного меню и горячих клавиш
var contextMenu = new ContextMenuStrip();
contextMenu.Items.Add("Добавить", null, (s, ev) => AddProduct());
contextMenu.Items.Add("Редактировать", null, (s, ev) => EditProduct());
contextMenu.Items.Add("Удалить", null, (s, ev) => DeleteProduct());
contextMenu.Items.Add("Создать документ", null, (s, ev) => CreateDocument());
contextMenu.Items.Add("Создать документ с таблицей", null, (s, ev) => CreateTableDocument());
contextMenu.Items.Add("Создать документ с диаграммой", null, (s, ev) => CreateChartDocument());
// Привязка контекстного меню к компоненту вывода списков
_productListControl.ContextMenuStrip = contextMenu;
// Настройка горячих клавиш
this.KeyDown += MainForm_KeyDown;
// Настройка панели инструментов
toolStrip = new ToolStrip();
toolStrip.Items.Add("Продукты", null, (s, ev) => OpenProductForm());
toolStrip.Items.Add("Категории", null, (s, ev) => OpenCategoryForm());
this.Controls.Add(toolStrip);
}
private void OpenProductForm()
{
var form = new ProductForm(_productLogic, _categoryLogic);
form.ShowDialog();
}
private void OpenCategoryForm()
{
var form = new CategoryForm(_categoryLogic);
if (form.ShowDialog() == DialogResult.OK)
{
LoadProducts();
}
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.A))
{
AddProduct();
return true;
}
else if (keyData == (Keys.Control | Keys.U))
{
EditProduct();
return true;
}
else if (keyData == (Keys.Control | Keys.D))
{
DeleteProduct();
return true;
}
else if (keyData == (Keys.Control | Keys.S))
{
CreateDocument();
return true;
}
else if (keyData == (Keys.Control | Keys.T))
{
CreateTableDocument();
return true;
}
else if (keyData == (Keys.Control | Keys.C))
{
CreateChartDocument();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control)
{
switch (e.KeyCode)
{
case Keys.A:
AddProduct();
break;
case Keys.U:
EditProduct();
break;
case Keys.D:
DeleteProduct();
break;
case Keys.S:
CreateDocument();
break;
case Keys.T:
CreateTableDocument();
break;
case Keys.C:
CreateChartDocument();
break;
}
}
}
private void AddProduct()
{
// Логика добавления нового продукта
var form = new ProductForm(_productLogic, _categoryLogic);
if (form.ShowDialog() == DialogResult.OK)
{
LoadProducts();
}
}
private void EditProduct()
{
// Логика редактирования выбранного продукта
var selectedProduct = _productListControl.GetSelectedObject<ProductViewModel>();
if (selectedProduct != null)
{
var form = new ProductForm(_productLogic, _categoryLogic, selectedProduct);
if (form.ShowDialog() == DialogResult.OK)
{
LoadProducts();
}
}
}
private void DeleteProduct()
{
// Логика удаления выбранного продукта
var selectedProduct = _productListControl.GetSelectedObject<ProductViewModel>();
if (selectedProduct != null)
{
var result = MessageBox.Show("Вы действительно хотите удалить этот продукт?", "Подтверждение", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
_productLogic.Delete(new ProductBindingModel { Id = selectedProduct.Id });
LoadProducts();
}
}
}
private void CreateDocument()
{
using (var saveFileDialog = new SaveFileDialog())
{
saveFileDialog.Filter = "Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
var products = _productLogic.ReadList(null);
var rows = products.Select(p => $"{p.Name} - {p.Description}").ToArray();
var component = new ComponentWithBigText();
component.CreateDocument(saveFileDialog.FileName, "Список продуктов", rows);
MessageBox.Show("Документ успешно создан.");
}
}
}
private void CreateTableDocument()
{
using (var saveFileDialog = new SaveFileDialog())
{
saveFileDialog.Filter = "Word files (*.docx)|*.docx|All files (*.*)|*.*";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
var products = _productLogic.ReadList(null);
if (products == null || products.Count == 0)
{
MessageBox.Show("Нет данных для создания документа.");
return;
}
var headers = new List<(int, int, string, string)>
{
(0, 0, "Id", "Id"),
(1, 0, "Name", "Name"),
(2, 0, "Category", "Category"),
(3, 0, "CountOnStorage", "CountOnStorage")
};
var columnsRowsWidth = new List<(int Column, int Row)>
{
(100, 0),
(200, 1),
(150, 2),
(150, 3)
};
var config = new WordTableWithData<ProductViewModel>
{
FileName = saveFileDialog.FileName,
Title = "Список продуктов",
Headers = headers,
Data = products,
ColumnsRowsWidth = columnsRowsWidth,
NullReplace = "-",
};
wordTablesComponent1.CreateTable(config);
MessageBox.Show("Документ успешно создан.");
}
}
}
private void CreateChartDocument()
{
using (var saveFileDialog = new SaveFileDialog())
{
saveFileDialog.Filter = "PDF files (*.pdf)|*.pdf|All files (*.*)|*.*";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
var products = _productLogic.ReadList(null);
var categories = products.Where(p => p.CountOnStorage == 0).GroupBy(p => p.Category)
.Select(g => new ChartData
{
SeriesName = g.Key,
Value = g.Count(p => p.CountOnStorage == 0)
}).ToList();
if (categories.Count == 0)
{
MessageBox.Show("Нет данных для создания диаграммы.");
return;
}
var component = new PdfCirclDiagr();
component.GeneratePdf(saveFileDialog.FileName,
"Диаграмма продуктов", "Продукты без наличия",
LegendPosition.Right,
categories);
MessageBox.Show("Документ успешно создан.");
}
}
}
}
}

View File

@ -0,0 +1,123 @@
<?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="wordTablesComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@ -0,0 +1,172 @@
using Library15Gerimovich;
using WinFormsLibrary1;
namespace Forms
{
partial class ProductForm
{
/// <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()
{
textBoxName = new TextBox();
textBoxDescription = new TextBox();
labelName = new Label();
labelDescription = new Label();
buttonSave = new Button();
buttonCancel = new Button();
labelCategory = new Label();
labelCountOnStorage = new Label();
_categoryComboBox = new ComboBoxUserControl();
_countOnStorageControl = new InputRealNumber();
SuspendLayout();
//
// textBoxName
//
textBoxName.Location = new Point(120, 25);
textBoxName.Margin = new Padding(3, 4, 3, 4);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(200, 27);
textBoxName.TabIndex = 0;
//
// textBoxDescription
//
textBoxDescription.Location = new Point(120, 76);
textBoxDescription.Margin = new Padding(3, 4, 3, 4);
textBoxDescription.Name = "textBoxDescription";
textBoxDescription.Size = new Size(200, 27);
textBoxDescription.TabIndex = 1;
//
// labelName
//
labelName.AutoSize = true;
labelName.Location = new Point(20, 29);
labelName.Name = "labelName";
labelName.Size = new Size(80, 20);
labelName.TabIndex = 2;
labelName.Text = "Название:";
//
// labelDescription
//
labelDescription.AutoSize = true;
labelDescription.Location = new Point(20, 79);
labelDescription.Name = "labelDescription";
labelDescription.Size = new Size(82, 20);
labelDescription.TabIndex = 3;
labelDescription.Text = "Описание:";
//
// buttonSave
//
buttonSave.Location = new Point(12, 358);
buttonSave.Margin = new Padding(3, 4, 3, 4);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(150, 38);
buttonSave.TabIndex = 4;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(190, 358);
buttonCancel.Margin = new Padding(3, 4, 3, 4);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(150, 38);
buttonCancel.TabIndex = 5;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// labelCategory
//
labelCategory.AutoSize = true;
labelCategory.Location = new Point(20, 129);
labelCategory.Name = "labelCategory";
labelCategory.Size = new Size(84, 20);
labelCategory.TabIndex = 6;
labelCategory.Text = "Категория:";
//
// labelCountOnStorage
//
labelCountOnStorage.AutoSize = true;
labelCountOnStorage.Location = new Point(23, 193);
labelCountOnStorage.Name = "labelCountOnStorage";
labelCountOnStorage.Size = new Size(81, 20);
labelCountOnStorage.TabIndex = 7;
labelCountOnStorage.Text = "На складе:";
//
// _categoryComboBox
//
_categoryComboBox.Location = new Point(120, 125);
_categoryComboBox.Margin = new Padding(4, 5, 4, 5);
_categoryComboBox.Name = "_categoryComboBox";
_categoryComboBox.SelectedValue = "";
_categoryComboBox.Size = new Size(200, 27);
_categoryComboBox.TabIndex = 0;
//
// _countOnStorageControl
//
_countOnStorageControl.Location = new Point(120, 161);
_countOnStorageControl.Margin = new Padding(3, 4, 3, 4);
_countOnStorageControl.Name = "_countOnStorageControl";
_countOnStorageControl.Size = new Size(192, 114);
_countOnStorageControl.TabIndex = 8;
//
// ProductForm
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(361, 409);
Controls.Add(_countOnStorageControl);
Controls.Add(_categoryComboBox);
Controls.Add(labelCountOnStorage);
Controls.Add(labelCategory);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(labelDescription);
Controls.Add(labelName);
Controls.Add(textBoxDescription);
Controls.Add(textBoxName);
Margin = new Padding(3, 4, 3, 4);
Name = "ProductForm";
Text = "Добавление/Редактирование продукта";
ResumeLayout(false);
PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox textBoxName;
private System.Windows.Forms.TextBox textBoxDescription;
private System.Windows.Forms.Label labelName;
private System.Windows.Forms.Label labelDescription;
private System.Windows.Forms.Button buttonSave;
private System.Windows.Forms.Button buttonCancel;
private System.Windows.Forms.Label labelCategory;
private System.Windows.Forms.Label labelCountOnStorage;
private ComboBoxUserControl _categoryComboBox;
private InputRealNumber _countOnStorageControl;
}
}

View File

@ -0,0 +1,81 @@
using System;
using System.Windows.Forms;
using Contracts.BindingModels;
using Contracts.BusinessLogicContracts;
using Contracts.ViewModels;
using Library15Gerimovich;
using WinFormsLibrary1;
namespace Forms
{
public partial class ProductForm : Form
{
private readonly IProductLogic _productLogic;
private readonly ICategoryLogic _categoryLogic;
private ProductViewModel _product;
private bool _isNewProduct;
public ProductForm(IProductLogic productLogic, ICategoryLogic categoryLogic, ProductViewModel product = null)
{
InitializeComponent();
_categoryLogic = categoryLogic;
_productLogic = productLogic;
_product = product;
_isNewProduct = product == null;
LoadCategories();
LoadProduct();
}
private void LoadCategories()
{
var categories = _categoryLogic.ReadList();
_categoryComboBox.ClearItems();
foreach (var category in categories)
{
_categoryComboBox.AddItem(category.Name);
}
}
private void LoadProduct()
{
if (_product != null)
{
textBoxName.Text = _product.Name;
textBoxDescription.Text = _product.Description;
_categoryComboBox.SelectedValue = _product.Category;
_countOnStorageControl.DoubleValue = _product.CountOnStorage;
}
}
private void buttonSave_Click(object sender, EventArgs e)
{
var model = new ProductBindingModel
{
Id = _product?.Id ?? 0,
Name = textBoxName.Text,
Description = textBoxDescription.Text,
Category = _categoryComboBox.SelectedValue,
CountOnStorage = (int)_countOnStorageControl.DoubleValue
};
if (_isNewProduct)
{
_productLogic.Create(model);
}
else
{
_productLogic.Update(model);
}
this.DialogResult = DialogResult.OK;
this.Close();
}
private void buttonCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,7 +1,19 @@
using BusinessLogics.BusinessLogics;
using Contracts.BusinessLogicContracts;
using Contracts.StorageContracts;
using DatabaseImplement.Implements;
using Forms;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace WinFormsApp1
{
internal static class Program
{
private static ServiceProvider? _serviceProvider;
public static ServiceProvider? ServiceProvider => _serviceProvider;
/// <summary>
/// The main entry point for the application.
/// </summary>
@ -11,7 +23,30 @@ namespace WinFormsApp1
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form2());
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
Application.Run(_serviceProvider.GetRequiredService<MainForm>());
}
private static void ConfigureServices(ServiceCollection services)
{
services.AddLogging(option =>
{
option.SetMinimumLevel(LogLevel.Information);
});
services.AddTransient<IProductStorage, ProductStorage>();
services.AddTransient<ICategoryStorage, CategoryStorage>();
services.AddTransient<IProductLogic, ProductLogic>();
services.AddTransient<ICategoryLogic, CategoryLogic>();
services.AddTransient<CategoryForm>();
services.AddTransient<ProductForm>();
services.AddTransient<MainForm>();
}
}
}

View File

@ -3,17 +3,17 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.34916.146
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Components", "WinFormsLibrary1\Components.csproj", "{4F13F436-1BE0-4F8D-A720-FCBF3893BA55}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinFormsLibrary1", "WinFormsLibrary1\WinFormsLibrary1.csproj", "{4F13F436-1BE0-4F8D-A720-FCBF3893BA55}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Forms", "WinFormsApp1\Forms.csproj", "{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Models", "Models\Models.csproj", "{C4816B78-EBAF-4183-8775-1180D91250D5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BusinessLogics", "Businesslogic\BusinessLogics.csproj", "{753AC945-F64F-4A41-9036-6450AAB5A890}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BusinessLogics", "Businesslogic\BusinessLogics.csproj", "{753AC945-F64F-4A41-9036-6450AAB5A890}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Contracts", "Contracts\Contracts.csproj", "{027FB9BF-E927-4C34-AFAD-C71EB03398EE}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contracts", "Contracts\Contracts.csproj", "{027FB9BF-E927-4C34-AFAD-C71EB03398EE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DatabaseImplement", "DatabaseImplement\DatabaseImplement.csproj", "{02E84641-9C21-43C3-99CD-765878F8C8F6}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DatabaseImplement", "DatabaseImplement\DatabaseImplement.csproj", "{02E84641-9C21-43C3-99CD-765878F8C8F6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@ -4,7 +4,7 @@ namespace WinFormsLibrary1
{
public partial class DateInputControl : UserControl
{
private string DateFormat{ get; set; }
public string DateFormat{ get; set; }
public DateInputControl()
{
@ -35,11 +35,13 @@ namespace WinFormsLibrary1
}
set
{
if (string.IsNullOrEmpty(DateFormat))
if (!string.IsNullOrEmpty(DateFormat))
{
textBoxDate.Text = value.ToString(DateFormat);
} else
{
textBoxDate.Text = string.Empty;
}
textBoxDate.Text = string.Empty;
}
}

View File

@ -6,6 +6,8 @@
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Version>1.0.2</Version>
<Title>Library13StroevV</Title>
</PropertyGroup>
<ItemGroup>