Compare commits

..

9 Commits
main ... lab3

Author SHA1 Message Date
DyCTaTOR
7bd3733c6e исправлен компонент 3 2024-11-14 20:27:58 +04:00
DyCTaTOR
f5a1ac2240 Lab3 is done 2024-11-11 22:20:20 +04:00
DyCTaTOR
40971f2997 Внутренняя логика 2024-10-27 15:16:44 +03:00
DyCTaTOR
3a02a9e7f2 lab2 - сдано 2024-10-15 10:57:48 +04:00
DyCTaTOR
4a3147a908 Merge branch 'lab1' into lab2 2024-10-15 10:29:29 +04:00
DyCTaTOR
86ac64ad42 lab1 - сдано 2024-10-15 10:29:10 +04:00
DyCTaTOR
ff464aea76 lab1 - modifed 2024-10-14 20:12:04 +04:00
DyCTaTOR
bdf15f37cd лаб2 - готово 2024-10-14 19:54:00 +04:00
DyCTaTOR
7bdd5ea8fb lab1 - почти готова 2024-10-14 13:05:17 +04:00
80 changed files with 4699 additions and 0 deletions

View File

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

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,103 @@
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 ProductLogic : IProductLogic
{
private readonly IProductStorage _productStorage;
public ProductLogic(IProductStorage productStorage)
{
_productStorage = productStorage;
}
public List<ProductViewModel> ReadList(ProductSearchModel? model)
{
var list = model == null ? _productStorage.GetFullList() : _productStorage.GetFilteredList(model);
if (list == null)
{
return null;
}
return list;
}
public ProductViewModel ReadElement(ProductSearchModel? model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
var element = _productStorage.GetElement(model);
if (element == null)
{
return null;
}
return element;
}
public bool Create(ProductBindingModel model)
{
CheckModel(model);
if (_productStorage.Insert(model) == null)
{
return false;
}
return true;
}
public bool Update(ProductBindingModel model)
{
CheckModel(model);
if (_productStorage.Update(model) == null)
{
return false;
}
return true;
}
public bool Delete(ProductBindingModel model)
{
CheckModel(model, false);
if (_productStorage.Delete(model) == null)
{
return false;
}
return true;
}
private void CheckModel(ProductBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.Name))
{
throw new ArgumentException("Введите название продукта", nameof(model.Name));
}
if (string.IsNullOrEmpty(model.Description))
{
throw new ArgumentException("Введите описание продукта", nameof(model.Description));
}
if (model.Category == null)
{
throw new ArgumentException("Введите категорию продукта", nameof(model.Category));
}
if (model.CountOnStorage < 0)
{
throw new ArgumentException("Укажите валидное число продукта на складе", nameof(model.CountOnStorage));
}
}
}
}

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

@ -0,0 +1,19 @@
using Models.Enums;
using Models.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.BindingModels
{
public class ProductBindingModel : IProductModel
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
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

@ -0,0 +1,20 @@
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 IProductLogic
{
List<ProductViewModel>? ReadList(ProductSearchModel? model);
ProductViewModel? ReadElement(ProductSearchModel? model);
bool Create(ProductBindingModel model);
bool Update(ProductBindingModel model);
bool Delete(ProductBindingModel model);
}
}

View File

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

View File

@ -0,0 +1,17 @@
using Models.Enums;
using Models.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.SearchModels
{
public class ProductSearchModel
{
public int? Id { get; set; }
public string? Name { 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,21 @@
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 IProductStorage
{
List<ProductViewModel> GetFullList();
List<ProductViewModel> GetFilteredList(ProductSearchModel model);
ProductViewModel? GetElement(ProductSearchModel model);
ProductViewModel? Insert(ProductBindingModel model);
ProductViewModel? Update(ProductBindingModel model);
ProductViewModel? Delete(ProductBindingModel 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; } = "Название категории";
}
}

View File

@ -0,0 +1,25 @@
using Models.Enums;
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 ProductViewModel
{
public string Id { get; set; }
[DisplayName("Название")]
public string Name { get; set; } = string.Empty;
[DisplayName("Описание")]
public string Description { get; set; } = string.Empty;
[DisplayName("Категория продукта")]
public string Category { get; set; } = string.Empty;
[DisplayName("Количество товаров на складе")]
public int? CountOnStorage { get; set; }
public string? CountOnStorageS { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using DatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
namespace DatabaseImplement
{
public class Database : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<Category> Categories { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql("Host=localhost;Port=5432;Database=kop;Username=postgres;Password=postgres");
}
}
}

View File

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\Models\Models.csproj" />
</ItemGroup>
</Project>

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,78 @@
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 ProductStorage : IProductStorage
{
public List<ProductViewModel> GetFullList()
{
using var context = new Database();
return context.Products.Select(x => x.GetViewModel).ToList();
}
public List<ProductViewModel> GetFilteredList(ProductSearchModel model)
{
if (string.IsNullOrEmpty(model.Name))
{
return new();
}
using var context = new Database();
return context.Products
.Where(x => x.Name == model.Name)
.Select(x => x.GetViewModel)
.ToList();
}
public ProductViewModel? GetElement(ProductSearchModel model)
{
if (!model.Id.HasValue)
{
return null;
}
using var context = new Database();
return context.Products.FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
}
public ProductViewModel? Insert(ProductBindingModel model)
{
var newProvider = Product.Create(model);
if (newProvider == null) return null;
using var context = new Database();
context.Products.Add(newProvider);
context.SaveChanges();
return newProvider.GetViewModel;
}
public ProductViewModel? Update(ProductBindingModel model)
{
using var context = new Database();
var provider = context.Products.FirstOrDefault(x => x.Id == model.Id);
if (provider == null) return null;
provider.Update(model);
context.SaveChanges();
return provider.GetViewModel;
}
public ProductViewModel? Delete(ProductBindingModel model)
{
using var context = new Database();
var element = context.Products.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
context.Products.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,56 @@
// <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("20241027113242_InitialCreate")]
partial class InitialCreate
{
/// <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.Product", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Category")
.HasColumnType("integer");
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,38 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace DatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Products",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
Description = table.Column<string>(type: "text", nullable: false),
Category = table.Column<int>(type: "integer", nullable: false),
CountOnStorage = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Products", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Products");
}
}
}

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

@ -0,0 +1,76 @@
// <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("20241112051510_nullableCountOnStorage")]
partial class nullableCountOnStorage
{
/// <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")
.IsRequired()
.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,22 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class nullableCountOnStorage : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

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("20241112052212_nullableCountOnStorage2")]
partial class nullableCountOnStorage2
{
/// <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,36 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class nullableCountOnStorage2 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<int>(
name: "CountOnStorage",
table: "Products",
type: "integer",
nullable: true,
oldClrType: typeof(int),
oldType: "integer");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<int>(
name: "CountOnStorage",
table: "Products",
type: "integer",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "integer",
oldNullable: true);
}
}
}

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", "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,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

@ -0,0 +1,64 @@
using Contracts.BindingModels;
using Contracts.ViewModels;
using Models.Enums;
using Models.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement.Models
{
public class Product : IProductModel
{
public int Id { get; private set; }
[Required]
public string Name { get; private set; } = string.Empty;
[Required]
public string Description { get; private set; } = string.Empty;
[Required]
public string Category { get; private set; }
public int? CountOnStorage { get; private set; }
public static Product? Create(ProductBindingModel model)
{
if (model == null) return null;
return new Product
{
Id = model.Id,
Name = model.Name,
Description = model.Description,
Category = model.Category,
CountOnStorage = model.CountOnStorage,
};
}
public void Update(ProductBindingModel model)
{
if (model == null) return;
Name = model.Name;
Description = model.Description;
Category = model.Category;
CountOnStorage = model.CountOnStorage;
}
public ProductViewModel GetViewModel => new()
{
Id = Id.ToString(),
Name = Name,
Description = Description,
Category = Category,
CountOnStorage = CountOnStorage,
CountOnStorageS = CountOnStorage != null ? CountOnStorage.ToString() : "Нет в наличии",
};
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Models.Enums
{
public enum Category
{
None,
Food,
Clothes,
House,
Health,
Technic,
Gift,
Sport
}
}

View File

@ -0,0 +1,7 @@
namespace Models
{
public interface IId
{
int Id { get;}
}
}

View File

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

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

@ -0,0 +1,17 @@
using Models.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Models.Models
{
public interface IProductModel : IId
{
string Name { get;}
string Description { 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

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

View File

@ -0,0 +1,37 @@
using System;
using System.Windows.Forms;
using WinFormsLibrary1;
namespace WinFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listBoxUserControl.SetParams("Id {Id} Íàçâàíèå {Name} Ôàìèëèÿ {Familia}", '{', '}');
listBoxUserControl.AddObject<User>(new User(1, "status1", "Vova", "Stroev", 19, "FIST", 35000.50));
listBoxUserControl.AddObject<User>(new User(1, "status2", "Vladimir", "Stroev", 20, "FIST", 33000.50));
listBoxUserControl.AddObject<User>(new User(1, "status3", "Volodya", "Stroev", 21, "FIST", 39000.50));
listBoxUserControl.AddObject<User>(new User(1, "status3", "Volodya", "Stroev", 21, "FIST", 39000.50));
listBoxUserControl.AddObject<User>(new User(1, "status3", "Volodya", "Stroev", 21, "FIST", 39000.50));
listBoxUserControl.AddObject<User>(new User(1, "status3", "Volodya", "Stroev", 21, "FIST", 39000.50));
listBoxUserControl.AddObject<User>(new User(1, "status3", "Volodya", "Stroev", 21, "FIST", 39000.50));
listBoxUserControl.AddObject<User>(new User(1, "status3", "Volodya", "Stroev", 21, "FIST", 39000.50));
listBoxUserControl.AddObject<User>(new User(1, "status3", "Volodya", "Stroev", 21, "FIST", 39000.50));
listBoxUserControl.AddObject<User>(new User(1, "status3", "Volodya", "Stroev", 21, "FIST", 39000.50));
listBoxUserControl.AddObject<User>(new User(1, "status3", "Volodya", "Stroev", 21, "FIST", 39000.50));
}
private void ComboBoxUserControl_SelectedValueChanged(object sender, EventArgs e)
{
MessageBox.Show($"ComboBox selected: {comboBoxUserControl.SelectedValue}");
}
/*private void ListBoxUserControl_SelectedValueChanged(object sender, EventArgs e)
{
MessageBox.Show($"ListBox selected: {listBoxUserControl.SelectedValue}");
}*/
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Library14Petrushin" Version="1.0.1" />
<PackageReference Include="Library15Gerimovich" Version="1.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Businesslogic\BusinessLogics.csproj" />
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\DatabaseImplement\DatabaseImplement.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();
_productTreeView = new Library14Petrushin.HierarchicalTreeView();
wordTablesComponent1 = new Library15Gerimovich.WordTablesComponent(components);
SuspendLayout();
//
// _productTreeView
//
_productTreeView.Dock = DockStyle.Fill;
_productTreeView.Location = new Point(0, 0);
_productTreeView.Margin = new Padding(3, 5, 3, 5);
_productTreeView.Name = "_productTreeView";
_productTreeView.SelectedNodeIndex = -1;
_productTreeView.Size = new Size(292, 521);
_productTreeView.TabIndex = 0;
//
// MainForm
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(292, 521);
Controls.Add(_productTreeView);
Margin = new Padding(3, 4, 3, 4);
Name = "MainForm";
Text = "Учет продуктов в магазине";
Load += MainForm_Load;
ResumeLayout(false);
}
#endregion
private Library14Petrushin.HierarchicalTreeView _productTreeView;
private Library15Gerimovich.WordTablesComponent wordTablesComponent1;
}
}

View File

@ -0,0 +1,285 @@
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);
var hierarchy = new List<string> { "Category", "CountOnStorageS", "Id", "Name" };
var alwaysNewBranch = new Dictionary<string, bool> { { "Name", true } };
_productTreeView.SetHierarchy(hierarchy, alwaysNewBranch);
foreach (var product in products)
{
_productTreeView.AddObjectToTree(product, "Name");
}
}
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());
// Привязка контекстного меню к компоненту вывода списков
_productTreeView.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 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 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 AddProduct()
{
var form = new ProductForm(_productLogic, _categoryLogic);
if (form.ShowDialog() == DialogResult.OK)
{
LoadProducts();
}
}
private void EditProduct()
{
var selectedProduct = _productTreeView.GetSelectedObject<ProductViewModel>();
selectedProduct = _productLogic.ReadElement(new ProductSearchModel
{
Id = int.Parse(selectedProduct.Id)
});
if (selectedProduct != null)
{
var form = new ProductForm(_productLogic, _categoryLogic, selectedProduct);
if (form.ShowDialog() == DialogResult.OK)
{
LoadProducts();
}
}
}
private void DeleteProduct()
{
var selectedProduct = _productTreeView.GetSelectedObject<ProductViewModel>();
selectedProduct = _productLogic.ReadElement(new ProductSearchModel
{
Id = int.Parse(selectedProduct.Id)
});
if (selectedProduct != null)
{
var result = MessageBox.Show("Вы действительно хотите удалить этот продукт?", "Подтверждение", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
_productLogic.Delete(new ProductBindingModel { Id = int.Parse(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 = string.IsNullOrEmpty(_product?.Id) ? 0 : int.Parse(_product?.Id),
Name = textBoxName.Text,
Description = textBoxDescription.Text,
Category = _categoryComboBox.SelectedValue,
CountOnStorage = _countOnStorageControl.DoubleValue != null ? (int?)_countOnStorageControl.DoubleValue : null
};
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

@ -0,0 +1,53 @@
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>
[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<Form1>());
}
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>();
services.AddTransient<Form1>();
}
}
}

View File

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

View File

@ -0,0 +1,55 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.34916.146
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinFormsLibrary1", "WinFormsLibrary1\WinFormsLibrary1.csproj", "{4F13F436-1BE0-4F8D-A720-FCBF3893BA55}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "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("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BusinessLogics", "Businesslogic\BusinessLogics.csproj", "{753AC945-F64F-4A41-9036-6450AAB5A890}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contracts", "Contracts\Contracts.csproj", "{027FB9BF-E927-4C34-AFAD-C71EB03398EE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DatabaseImplement", "DatabaseImplement\DatabaseImplement.csproj", "{02E84641-9C21-43C3-99CD-765878F8C8F6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4F13F436-1BE0-4F8D-A720-FCBF3893BA55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4F13F436-1BE0-4F8D-A720-FCBF3893BA55}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F13F436-1BE0-4F8D-A720-FCBF3893BA55}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4F13F436-1BE0-4F8D-A720-FCBF3893BA55}.Release|Any CPU.Build.0 = Release|Any CPU
{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}.Release|Any CPU.Build.0 = Release|Any CPU
{C4816B78-EBAF-4183-8775-1180D91250D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C4816B78-EBAF-4183-8775-1180D91250D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C4816B78-EBAF-4183-8775-1180D91250D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C4816B78-EBAF-4183-8775-1180D91250D5}.Release|Any CPU.Build.0 = Release|Any CPU
{753AC945-F64F-4A41-9036-6450AAB5A890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{753AC945-F64F-4A41-9036-6450AAB5A890}.Debug|Any CPU.Build.0 = Debug|Any CPU
{753AC945-F64F-4A41-9036-6450AAB5A890}.Release|Any CPU.ActiveCfg = Release|Any CPU
{753AC945-F64F-4A41-9036-6450AAB5A890}.Release|Any CPU.Build.0 = Release|Any CPU
{027FB9BF-E927-4C34-AFAD-C71EB03398EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{027FB9BF-E927-4C34-AFAD-C71EB03398EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{027FB9BF-E927-4C34-AFAD-C71EB03398EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{027FB9BF-E927-4C34-AFAD-C71EB03398EE}.Release|Any CPU.Build.0 = Release|Any CPU
{02E84641-9C21-43C3-99CD-765878F8C8F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{02E84641-9C21-43C3-99CD-765878F8C8F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{02E84641-9C21-43C3-99CD-765878F8C8F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{02E84641-9C21-43C3-99CD-765878F8C8F6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {30BE3CA4-B770-4A5A-A07E-FE2B703C6B13}
EndGlobalSection
EndGlobal

View File

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

View File

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

View File

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

View File

@ -0,0 +1,36 @@
namespace WinFormsLibrary1
{
partial class ComponentDiagram
{
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

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

View File

@ -0,0 +1,36 @@
namespace WinFormsLibrary1
{
partial class ComponentTable
{
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,43 @@
namespace WinFormsLibrary1
{
partial class ListBoxUserControl
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
listBox = new ListBox();
SuspendLayout();
//
// listBox
//
listBox.FormattingEnabled = true;
listBox.Location = new Point(0, 0);
listBox.Margin = new Padding(4, 5, 4, 5);
listBox.Name = "listBox";
listBox.Size = new Size(594, 144);
listBox.TabIndex = 0;
//
// ListBoxUserControl
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(listBox);
Margin = new Padding(4, 5, 4, 5);
Name = "ListBoxUserControl";
Size = new Size(598, 146);
ResumeLayout(false);
}
private System.Windows.Forms.ListBox listBox;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,39 @@
namespace WinFormsLibrary2
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinFormsLibrary2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View File

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

View File

@ -0,0 +1,37 @@
namespace WinFormsLibrary2
{
partial class UserControl1
{
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
}
#endregion
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinFormsLibrary2
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
}
}

View File

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

View File

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