Compare commits

...

5 Commits
main ... lab_4

Author SHA1 Message Date
sardq
a4e1485bc6 4 lab 2024-11-13 16:00:48 +04:00
sardq
c25cbeed77 3 lab ready 2024-10-30 15:22:19 +04:00
sardq
d398882215 лаба 3 без view модуля 2024-10-29 20:51:14 +04:00
sardq
52ad12538d 2.3 component + refactoring 2024-10-18 20:27:08 +04:00
sardq
f1591601e5 lab 1+2(2 components) 2024-10-04 11:08:55 +04:00
81 changed files with 4296 additions and 144 deletions

View File

@ -0,0 +1,77 @@
using ClientRecordContracts.BindingModels;
using ClientRecordContracts.BusinessLogicContracts;
using ClientRecordContracts.SearchModels;
using ClientRecordContracts.StoragesContracts;
using ClientRecordContracts.ViewModels;
using System.Collections.Generic;
namespace ClientRecordBuisinessLogic.BuisinessLogic
{
public class ClientLogic : IClientLogic
{
public IClientStorage _clientStorage;
public ClientLogic(IClientStorage clientStorage)
{
_clientStorage= clientStorage;
}
public bool Create(ClientBindingModel model)
{
CheckModel(model);
return _clientStorage.Insert(model)!= null;
}
public bool Delete(ClientBindingModel model)
{
CheckModel(model,false);
return _clientStorage.Delete(model) != null;
}
public ClientViewModel? ReadElement(ClientSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
return _clientStorage.GetElement(model) ;
}
public List<ClientViewModel>? ReadList(ClientSearchModel? model)
{
return model == null ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(model);
}
public bool Update(ClientBindingModel model)
{
CheckModel(model);
return _clientStorage.Update(model) != null;
}
private void CheckModel(ClientBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.ClientFIO))
{
throw new ArgumentNullException("Нет ФИО клиента", nameof(model.ClientFIO));
}
if (model.StatusId <= 0)
{
throw new ArgumentNullException("Некорректный идентификатор статуса", nameof(model.StatusId));
}
var element = _clientStorage.GetElement(new ClientSearchModel
{
ClientFIO = model.ClientFIO
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Клиент с таким ФИО уже есть");
}
}
}
}

View File

@ -0,0 +1,72 @@
using ClientRecordContracts.BindingModels;
using ClientRecordContracts.BusinessLogicContracts;
using ClientRecordContracts.SearchModels;
using ClientRecordContracts.StoragesContracts;
using ClientRecordContracts.ViewModels;
namespace ClientRecordBuisinessLogic.BuisinessLogic
{
public class StatusLogic : IStatusLogic
{
public IStatusStorage _statusStorage;
public StatusLogic(IStatusStorage statusStorage)
{
_statusStorage = statusStorage;
}
public bool Create(StatusBindingModel model)
{
CheckModel(model);
return _statusStorage.Insert(model) != null;
}
public bool Delete(StatusBindingModel model)
{
CheckModel(model);
return _statusStorage.Delete(model) != null;
}
public StatusViewModel? ReadElement(StatusSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
return _statusStorage.GetElement(model);
}
public List<StatusViewModel>? ReadList(StatusSearchModel? model)
{
return model == null ? _statusStorage.GetFullList() : _statusStorage.GetFilteredList(model);
}
public bool Update(StatusBindingModel model)
{
CheckModel(model);
return _statusStorage.Update(model) != null;
}
private void CheckModel(StatusBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.Name))
{
throw new ArgumentNullException("Нет названия статуса", nameof(model.Name));
}
var element = _statusStorage.GetElement(new StatusSearchModel
{
Name = model.Name
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Статус с таким названием уже есть");
}
}
}
}

View File

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

View File

@ -0,0 +1,14 @@
using ClientRecordDataModels.Models;
namespace ClientRecordContracts.BindingModels
{
public class ClientBindingModel : IClientModel
{
public int Id { get; set; }
public string? Reviews { get; set; }
public string ClientFIO { get; set; } = string.Empty;
public int? Amount { get; set; }
public int StatusId { get; set; }
}
}

View File

@ -0,0 +1,10 @@
using ClientRecordDataModels.Models;
namespace ClientRecordContracts.BindingModels
{
public class StatusBindingModel : IStatusModel
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,20 @@
using ClientRecordContracts.BindingModels;
using ClientRecordContracts.SearchModels;
using ClientRecordContracts.ViewModels;
namespace ClientRecordContracts.BusinessLogicContracts
{
public interface IClientLogic
{
List<ClientViewModel>? ReadList(ClientSearchModel? model);
ClientViewModel? ReadElement(ClientSearchModel model);
bool Create(ClientBindingModel model);
bool Update(ClientBindingModel model);
bool Delete(ClientBindingModel model);
}
}

View File

@ -0,0 +1,19 @@
using ClientRecordContracts.BindingModels;
using ClientRecordContracts.SearchModels;
using ClientRecordContracts.ViewModels;
namespace ClientRecordContracts.BusinessLogicContracts
{
public interface IStatusLogic
{
List<StatusViewModel>? ReadList(StatusSearchModel? model);
StatusViewModel? ReadElement(StatusSearchModel model);
bool Create(StatusBindingModel model);
bool Update(StatusBindingModel model);
bool Delete(StatusBindingModel model);
}
}

View File

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

View File

@ -0,0 +1,9 @@
namespace ClientRecordContracts.SearchModels
{
public class ClientSearchModel
{
public int? Id { get; set; }
public int? StatusId { get; set; }
public string? ClientFIO { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace ClientRecordContracts.SearchModels
{
public class StatusSearchModel
{
public int? Id { get; set; }
public string? Name { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using ClientRecordContracts.BindingModels;
using ClientRecordContracts.SearchModels;
using ClientRecordContracts.ViewModels;
namespace ClientRecordContracts.StoragesContracts
{
public interface IClientStorage
{
List<ClientViewModel> GetFullList();
List<ClientViewModel> GetFilteredList(ClientSearchModel model);
ClientViewModel? GetElement(ClientSearchModel model);
ClientViewModel? Insert(ClientBindingModel model);
ClientViewModel? Update(ClientBindingModel model);
ClientViewModel? Delete(ClientBindingModel model);
}
}

View File

@ -0,0 +1,21 @@
using ClientRecordContracts.BindingModels;
using ClientRecordContracts.SearchModels;
using ClientRecordContracts.ViewModels;
namespace ClientRecordContracts.StoragesContracts
{
public interface IStatusStorage
{
List<StatusViewModel> GetFullList();
List<StatusViewModel> GetFilteredList(StatusSearchModel model);
StatusViewModel? GetElement(StatusSearchModel model);
StatusViewModel? Insert(StatusBindingModel model);
StatusViewModel? Update(StatusBindingModel model);
StatusViewModel? Delete(StatusBindingModel model);
}
}

View File

@ -0,0 +1,23 @@
using ClientRecordDataModels.Models;
using System.ComponentModel;
namespace ClientRecordContracts.ViewModels
{
public class ClientViewModel : IClientModel
{
public int Id { get; set; }
[DisplayName("ФИО")]
public string ClientFIO { get; set; } = string.Empty;
[DisplayName("Отзывы")]
public string? Reviews { get; set; }
[DisplayName("Сумма покупок")]
public int? Amount { get; set; }
public int StatusId { get; set; }
[DisplayName("Статус")]
public string Status { get; set; } = string.Empty;
public string AmountString { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,13 @@
using ClientRecordDataModels.Models;
using System.ComponentModel;
namespace ClientRecordContracts.ViewModels
{
public class StatusViewModel : IStatusModel
{
public int Id { get; set; }
[DisplayName("Название статуса")]
public string Name { get; set; } = string.Empty;
}
}

View File

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

View File

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

View File

@ -0,0 +1,10 @@
namespace ClientRecordDataModels.Models
{
public interface IClientModel : IId
{
string ClientFIO{ get; }
string? Reviews{ get; }
int? Amount{ get; }
int StatusId{ get; }
}
}

View File

@ -0,0 +1,7 @@
namespace ClientRecordDataModels.Models
{
public interface IStatusModel :IId
{
string Name { get; }
}
}

View File

@ -0,0 +1,25 @@
using ClientRecordDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
namespace ClientRecordDatabaseImplement
{
public class ClientRecordDatabase : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (optionsBuilder.IsConfigured == false)
{
optionsBuilder.UseNpgsql(@"Host=localhost;Database=COP;Username=postgres;Password=postgres");
}
base.OnConfiguring(optionsBuilder);
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
AppContext.SetSwitch("Npgsql.DisableDataTimeInfinityConversions", true);
}
public virtual DbSet<Client> Clients { set; get; }
public virtual DbSet<Status> Statuses { set; get; }
}
}

View File

@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Folder Include="Migrations\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.35" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.35" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.35">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.29" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ClientRecordContracts\ClientRecordContracts.csproj" />
<ProjectReference Include="..\ClientRecordDataModels\ClientRecordDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,103 @@
using ClientRecordContracts.BindingModels;
using ClientRecordContracts.SearchModels;
using ClientRecordContracts.StoragesContracts;
using ClientRecordContracts.ViewModels;
using ClientRecordDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
namespace ClientRecordDatabaseImplement.Implements
{
public class ClientStorage : IClientStorage
{
public ClientViewModel? Delete(ClientBindingModel model)
{
using var context = new ClientRecordDatabase();
var element = context.Clients.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
var deletedElement = context.Clients
.Include(x => x.Status)
.FirstOrDefault(x => x.Id == model.Id)
?.GetViewModel;
context.Clients.Remove(element);
context.SaveChanges();
return deletedElement;
}
return null;
}
public ClientViewModel? GetElement(ClientSearchModel model)
{
if (string.IsNullOrEmpty(model.ClientFIO) && !model.Id.HasValue)
{
return null;
}
using var context = new ClientRecordDatabase();
return context.Clients
.Include(x => x.Status)
.FirstOrDefault(x => !string.IsNullOrEmpty(model.ClientFIO) && x.ClientFIO == model.ClientFIO ||
model.Id.HasValue && x.Id == model.Id)
?.GetViewModel;
}
public List<ClientViewModel> GetFilteredList(ClientSearchModel model)
{
using var context = new ClientRecordDatabase();
if (model.StatusId.HasValue)
{
return context.Clients
.Include(x => x.Status)
.Where(x => x.StatusId == model.StatusId)
.Select(x => x.GetViewModel)
.ToList();
}
return new();
}
public List<ClientViewModel> GetFullList()
{
using var context = new ClientRecordDatabase();
return context.Clients
.Include(x => x.Status)
.Select(x => x.GetViewModel)
.ToList();
}
public ClientViewModel? Insert(ClientBindingModel model)
{
var newClient = Client.Create(model);
if (newClient == null)
{
return null;
}
using var context = new ClientRecordDatabase();
context.Clients.Add(newClient);
context.SaveChanges();
return context.Clients
.Include(x => x.Status)
.FirstOrDefault(x => x.Id == newClient.Id)
?.GetViewModel;
}
public ClientViewModel? Update(ClientBindingModel model)
{
using var context = new ClientRecordDatabase();
var client = context.Clients.FirstOrDefault(x => x.Id == model.Id);
if (client == null)
{
return null;
}
client.Update(model);
context.SaveChanges();
return context.Clients
.Include(x => x.Status)
.FirstOrDefault(x => x.Id == model.Id)
?.GetViewModel;
}
}
}

View File

@ -0,0 +1,90 @@
using ClientRecordContracts.BindingModels;
using ClientRecordContracts.SearchModels;
using ClientRecordContracts.StoragesContracts;
using ClientRecordContracts.ViewModels;
using ClientRecordDatabaseImplement.Models;
using System.Data;
namespace ClientRecordDatabaseImplement.Implements
{
public class StatusStorage : IStatusStorage
{
public StatusViewModel? Delete(StatusBindingModel model)
{
using var context = new ClientRecordDatabase();
var element = context.Statuses.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Statuses.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
public StatusViewModel? GetElement(StatusSearchModel model)
{
if (string.IsNullOrEmpty(model.Name) && !model.Id.HasValue)
{
return null;
}
using var context = new ClientRecordDatabase();
return context.Statuses
.FirstOrDefault(x => !string.IsNullOrEmpty(model.Name) && x.Name == model.Name ||
model.Id.HasValue && x.Id == model.Id)
?.GetViewModel;
}
public List<StatusViewModel> GetFilteredList(StatusSearchModel model)
{
if (string.IsNullOrEmpty(model.Name))
{
return new();
}
using var context = new ClientRecordDatabase();
return context.Statuses
.Where(x => x.Name.Contains(model.Name))
.Select(x => x.GetViewModel)
.ToList();
}
public List<StatusViewModel> GetFullList()
{
using var context = new ClientRecordDatabase();
return context.Statuses
.Select(x => x.GetViewModel)
.ToList();
}
public StatusViewModel? Insert(StatusBindingModel model)
{
var newStatus = Status.Create(model);
if (newStatus == null)
{
return null;
}
using var context = new ClientRecordDatabase();
context.Statuses.Add(newStatus);
context.SaveChanges();
return newStatus.GetViewModel;
}
public StatusViewModel? Update(StatusBindingModel model)
{
using var context = new ClientRecordDatabase();
var status = context.Statuses.FirstOrDefault(x => x.Id == model.Id);
if (status == null)
{
return null;
}
status.Update(model);
context.SaveChanges();
return status.GetViewModel;
}
}
}

View File

@ -0,0 +1,93 @@
// <auto-generated />
using System;
using ClientRecordDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ClientRecordDatabaseImplement.Migrations
{
[DbContext(typeof(ClientRecordDatabase))]
[Migration("20241030093837_init")]
partial class init
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.35")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("ClientRecordDatabaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("Amount")
.HasColumnType("integer");
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("text");
b.Property<int>("ClientId")
.HasColumnType("integer");
b.Property<string>("Reviews")
.HasColumnType("text");
b.Property<int>("StatusId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("ClientId");
b.ToTable("Clients");
});
modelBuilder.Entity("ClientRecordDatabaseImplement.Models.Status", 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("Statuses");
});
modelBuilder.Entity("ClientRecordDatabaseImplement.Models.Client", b =>
{
b.HasOne("ClientRecordDatabaseImplement.Models.Status", "Status")
.WithMany("Clients")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Status");
});
modelBuilder.Entity("ClientRecordDatabaseImplement.Models.Status", b =>
{
b.Navigation("Clients");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,63 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ClientRecordDatabaseImplement.Migrations
{
public partial class init : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Statuses",
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_Statuses", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Clients",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ClientFIO = table.Column<string>(type: "text", nullable: false),
StatusId = table.Column<int>(type: "integer", nullable: false),
ClientId = table.Column<int>(type: "integer", nullable: false),
Reviews = table.Column<string>(type: "text", nullable: true),
Amount = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Clients", x => x.Id);
table.ForeignKey(
name: "FK_Clients_Statuses_ClientId",
column: x => x.ClientId,
principalTable: "Statuses",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Clients_ClientId",
table: "Clients",
column: "ClientId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Clients");
migrationBuilder.DropTable(
name: "Statuses");
}
}
}

View File

@ -0,0 +1,90 @@
// <auto-generated />
using System;
using ClientRecordDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ClientRecordDatabaseImplement.Migrations
{
[DbContext(typeof(ClientRecordDatabase))]
[Migration("20241030102017_fix")]
partial class fix
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.35")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("ClientRecordDatabaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("Amount")
.HasColumnType("integer");
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Reviews")
.HasColumnType("text");
b.Property<int>("StatusId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("StatusId");
b.ToTable("Clients");
});
modelBuilder.Entity("ClientRecordDatabaseImplement.Models.Status", 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("Statuses");
});
modelBuilder.Entity("ClientRecordDatabaseImplement.Models.Client", b =>
{
b.HasOne("ClientRecordDatabaseImplement.Models.Status", "Status")
.WithMany("Clients")
.HasForeignKey("StatusId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Status");
});
modelBuilder.Entity("ClientRecordDatabaseImplement.Models.Status", b =>
{
b.Navigation("Clients");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,68 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ClientRecordDatabaseImplement.Migrations
{
public partial class fix : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Clients_Statuses_ClientId",
table: "Clients");
migrationBuilder.DropIndex(
name: "IX_Clients_ClientId",
table: "Clients");
migrationBuilder.DropColumn(
name: "ClientId",
table: "Clients");
migrationBuilder.CreateIndex(
name: "IX_Clients_StatusId",
table: "Clients",
column: "StatusId");
migrationBuilder.AddForeignKey(
name: "FK_Clients_Statuses_StatusId",
table: "Clients",
column: "StatusId",
principalTable: "Statuses",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Clients_Statuses_StatusId",
table: "Clients");
migrationBuilder.DropIndex(
name: "IX_Clients_StatusId",
table: "Clients");
migrationBuilder.AddColumn<int>(
name: "ClientId",
table: "Clients",
type: "integer",
nullable: false,
defaultValue: 0);
migrationBuilder.CreateIndex(
name: "IX_Clients_ClientId",
table: "Clients",
column: "ClientId");
migrationBuilder.AddForeignKey(
name: "FK_Clients_Statuses_ClientId",
table: "Clients",
column: "ClientId",
principalTable: "Statuses",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
}
}

View File

@ -0,0 +1,88 @@
// <auto-generated />
using System;
using ClientRecordDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ClientRecordDatabaseImplement.Migrations
{
[DbContext(typeof(ClientRecordDatabase))]
partial class ClientRecordDatabaseModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.35")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("ClientRecordDatabaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("Amount")
.HasColumnType("integer");
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Reviews")
.HasColumnType("text");
b.Property<int>("StatusId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("StatusId");
b.ToTable("Clients");
});
modelBuilder.Entity("ClientRecordDatabaseImplement.Models.Status", 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("Statuses");
});
modelBuilder.Entity("ClientRecordDatabaseImplement.Models.Client", b =>
{
b.HasOne("ClientRecordDatabaseImplement.Models.Status", "Status")
.WithMany("Clients")
.HasForeignKey("StatusId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Status");
});
modelBuilder.Entity("ClientRecordDatabaseImplement.Models.Status", b =>
{
b.Navigation("Clients");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,58 @@
using ClientRecordContracts.BindingModels;
using ClientRecordContracts.ViewModels;
using System.ComponentModel.DataAnnotations;
using ClientRecordDataModels.Models;
namespace ClientRecordDatabaseImplement.Models
{
public class Client : IClientModel
{
public int Id { get; private set; }
[Required]
public string ClientFIO { get; set; } = string.Empty;
[Required]
public int StatusId { get; set; }
public virtual Status Status { get; set; }
public string? Reviews { get; set; }
public int? Amount { get; set; }
public static Client? Create(ClientBindingModel model)
{
if (model == null)
{
return null;
}
return new Client()
{
Id = model.Id,
ClientFIO = model.ClientFIO,
StatusId = model.StatusId,
Reviews = model.Reviews,
Amount = model.Amount,
};
}
public void Update(ClientBindingModel model)
{
if (model == null)
{
return;
}
ClientFIO= model.ClientFIO;
StatusId= model.StatusId;
Reviews= model.Reviews;
Amount = model.Amount;
}
public ClientViewModel GetViewModel => new()
{
Id = Id,
ClientFIO = ClientFIO,
StatusId = StatusId,
Reviews = Reviews,
Amount = Amount,
Status = Status.Name ?? string.Empty
};
}
}

View File

@ -0,0 +1,57 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using ClientRecordDataModels.Models;
using System.Security.Principal;
using ClientRecordContracts.BindingModels;
using ClientRecordContracts.ViewModels;
namespace ClientRecordDatabaseImplement.Models
{
public class Status : IStatusModel
{
public int Id { get; private set; }
[Required]
public string Name { get; private set; } = string.Empty;
[ForeignKey("StatusId")]
public virtual List<Client> Clients { get; set; } = new();
public static Status? Create(StatusBindingModel model)
{
if (model == null)
{
return null;
}
return new Status()
{
Id = model.Id,
Name = model.Name,
};
}
public static Status Create(StatusViewModel model)
{
return new Status
{
Id = model.Id,
Name = model.Name,
};
}
public void Update(StatusBindingModel model)
{
if (model == null)
{
return;
}
Name = model.Name;
}
public StatusViewModel GetViewModel => new()
{
Id = Id,
Name = Name,
};
}
}

View File

@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net7.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Components" Version="1.0.0" />
<PackageReference Include="ComponentsLibraryNet60" Version="1.0.0" />
<PackageReference Include="ControlsLibraryNet60" Version="1.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.35">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ClientRecordBuisinessLogic\ClientRecordBuisinessLogic.csproj" />
<ProjectReference Include="..\ClientRecordContracts\ClientRecordContracts.csproj" />
<ProjectReference Include="..\ClientRecordDatabaseImplement\ClientRecordDatabaseImplement.csproj" />
<ProjectReference Include="..\PluginConventionLibrary\PluginConventionLibrary.csproj" />
<ProjectReference Include="..\WinFormsLibrary\WinFormsLibraryRazubaev.csproj" />
</ItemGroup>
</Project>

190
ClientRecordView/FormClient.Designer.cs generated Normal file
View File

@ -0,0 +1,190 @@
namespace ClientRecordView
{
partial class FormClient
{
/// <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.buttonCancel = new System.Windows.Forms.Button();
this.labelStatus = new System.Windows.Forms.Label();
this.labelAmount = new System.Windows.Forms.Label();
this.labelReviews = new System.Windows.Forms.Label();
this.labelFIO = new System.Windows.Forms.Label();
this.buttonSave = new System.Windows.Forms.Button();
this.textBoxReviews = new System.Windows.Forms.TextBox();
this.textBoxFIO = new System.Windows.Forms.TextBox();
this.userControlIntegerInput = new Components.UserControlIntegerInput();
this.dropDownList = new WinFormsLibrary.DropDownList();
this.SuspendLayout();
//
// buttonCancel
//
this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.buttonCancel.Location = new System.Drawing.Point(258, 392);
this.buttonCancel.Margin = new System.Windows.Forms.Padding(4);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(131, 45);
this.buttonCancel.TabIndex = 17;
this.buttonCancel.Text = "Отмена";
this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
//
// labelStatus
//
this.labelStatus.AutoSize = true;
this.labelStatus.Location = new System.Drawing.Point(13, 9);
this.labelStatus.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.labelStatus.Name = "labelStatus";
this.labelStatus.Size = new System.Drawing.Size(63, 25);
this.labelStatus.TabIndex = 15;
this.labelStatus.Text = "Статус";
//
// labelAmount
//
this.labelAmount.AutoSize = true;
this.labelAmount.Location = new System.Drawing.Point(20, 283);
this.labelAmount.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.labelAmount.Name = "labelAmount";
this.labelAmount.Size = new System.Drawing.Size(141, 25);
this.labelAmount.TabIndex = 14;
this.labelAmount.Text = "Сумма покупок";
//
// labelReviews
//
this.labelReviews.AutoSize = true;
this.labelReviews.Location = new System.Drawing.Point(13, 193);
this.labelReviews.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.labelReviews.Name = "labelReviews";
this.labelReviews.Size = new System.Drawing.Size(77, 25);
this.labelReviews.TabIndex = 13;
this.labelReviews.Text = "Отзывы";
//
// labelFIO
//
this.labelFIO.AutoSize = true;
this.labelFIO.Location = new System.Drawing.Point(13, 99);
this.labelFIO.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.labelFIO.Name = "labelFIO";
this.labelFIO.Size = new System.Drawing.Size(52, 25);
this.labelFIO.TabIndex = 12;
this.labelFIO.Text = "ФИО";
//
// buttonSave
//
this.buttonSave.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.buttonSave.Location = new System.Drawing.Point(13, 392);
this.buttonSave.Margin = new System.Windows.Forms.Padding(4);
this.buttonSave.Name = "buttonSave";
this.buttonSave.Size = new System.Drawing.Size(131, 45);
this.buttonSave.TabIndex = 16;
this.buttonSave.Text = "Сохранить";
this.buttonSave.UseVisualStyleBackColor = true;
this.buttonSave.Click += new System.EventHandler(this.buttonSave_Click);
//
// textBoxReviews
//
this.textBoxReviews.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBoxReviews.Location = new System.Drawing.Point(13, 232);
this.textBoxReviews.Margin = new System.Windows.Forms.Padding(4);
this.textBoxReviews.Name = "textBoxReviews";
this.textBoxReviews.Size = new System.Drawing.Size(376, 31);
this.textBoxReviews.TabIndex = 11;
this.textBoxReviews.TextChanged += new System.EventHandler(this.textBoxReviews_TextChanged);
//
// textBoxFIO
//
this.textBoxFIO.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBoxFIO.Location = new System.Drawing.Point(13, 137);
this.textBoxFIO.Margin = new System.Windows.Forms.Padding(4);
this.textBoxFIO.Name = "textBoxFIO";
this.textBoxFIO.Size = new System.Drawing.Size(376, 31);
this.textBoxFIO.TabIndex = 10;
this.textBoxFIO.TextChanged += new System.EventHandler(this.textBoxFIO_TextChanged);
//
// userControlIntegerInput
//
this.userControlIntegerInput.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.userControlIntegerInput.Location = new System.Drawing.Point(13, 324);
this.userControlIntegerInput.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.userControlIntegerInput.Name = "userControlIntegerInput";
this.userControlIntegerInput.Size = new System.Drawing.Size(384, 75);
this.userControlIntegerInput.TabIndex = 19;
//
// dropDownList
//
this.dropDownList.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dropDownList.Location = new System.Drawing.Point(13, 37);
this.dropDownList.Name = "dropDownList";
this.dropDownList.Selected = "";
this.dropDownList.Size = new System.Drawing.Size(376, 51);
this.dropDownList.TabIndex = 20;
//
// FormClient
//
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(402, 450);
this.Controls.Add(this.dropDownList);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.labelStatus);
this.Controls.Add(this.labelAmount);
this.Controls.Add(this.labelReviews);
this.Controls.Add(this.labelFIO);
this.Controls.Add(this.buttonSave);
this.Controls.Add(this.textBoxReviews);
this.Controls.Add(this.textBoxFIO);
this.Controls.Add(this.userControlIntegerInput);
this.Name = "FormClient";
this.Text = "Клиент";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormClient_FormClosing);
this.Load += new System.EventHandler(this.FormClient_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Button buttonCancel;
private Label labelStatus;
private Label labelAmount;
private Label labelReviews;
private Label labelFIO;
private Button buttonSave;
private TextBox textBoxReviews;
private TextBox textBoxFIO;
private Components.UserControlIntegerInput userControlIntegerInput;
private WinFormsLibrary.DropDownList dropDownList;
}
}

View File

@ -0,0 +1,125 @@
using ClientRecordContracts.BindingModels;
using ClientRecordContracts.BusinessLogicContracts;
using ClientRecordContracts.SearchModels;
using ClientRecordContracts.ViewModels;
using DocumentFormat.OpenXml.Vml.Office;
namespace ClientRecordView
{
public partial class FormClient : Form
{
private int? _id;
private bool _isModified = false;
private readonly IClientLogic _clientlogic;
private readonly IStatusLogic _statusLogic;
private List<StatusViewModel> _statuses;
public int Id { set { _id = value; } }
public FormClient(IClientLogic logic, IStatusLogic statusLogic)
{
InitializeComponent();
_clientlogic = logic;
_statusLogic = statusLogic;
_statuses = new List<StatusViewModel>();
dropDownList.ValueChanged += (_, _) => _isModified = true;
userControlIntegerInput.ElementChanged += (_, _) => _isModified = true;
}
private void FormClient_Load(object sender, EventArgs e)
{
_statuses = _statusLogic.ReadList(null) ?? throw new Exception("Íå óäàëîñü ïîëó÷èòü ñïèñîê ñòàòóñîâ");
dropDownList.LoadValues(_statuses.Select(x => x.Name).ToList());
if (_id.HasValue)
{
try
{
var client = _clientlogic.ReadElement(new ClientSearchModel { Id = _id.Value });
if (client != null)
{
textBoxFIO.Text = client.ClientFIO;
textBoxReviews.Text = client.Reviews;
userControlIntegerInput.InputtedInteger = client.Amount;
dropDownList.Selected = client.Status;
_isModified = false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxFIO.Text))
{
MessageBox.Show("Çàïîëíèòå ÔÈÎ", "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(dropDownList.Selected))
{
MessageBox.Show("Âûáåðèòå ñòàòóñ", "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
var model = new ClientBindingModel
{
Id = _id ?? 0,
ClientFIO = textBoxFIO.Text,
Reviews = textBoxReviews.Text,
Amount = userControlIntegerInput.InputtedInteger,
StatusId = _statuses.First(x => x.Name == dropDownList.Selected).Id,
};
var operationResult = _id.HasValue ? _clientlogic.Update(model) : _clientlogic.Create(model);
if (!operationResult)
{
throw new Exception("Îøèáêà ïðè ñîõðàíåíèè");
}
MessageBox.Show("Ñîõðàíåíèå ïðîøëî óñïåøíî", "Ñîîáùåíèå", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private void textBoxFIO_TextChanged(object sender, EventArgs e)
{
_isModified = true;
}
private void textBoxReviews_TextChanged(object sender, EventArgs e)
{
_isModified = true;
}
private void FormClient_FormClosing(object sender, FormClosingEventArgs e)
{
if (!_isModified || DialogResult == DialogResult.OK)
return;
var result = MessageBox.Show(
"Ó âàñ åñòü íåñîõðàí¸ííûå èçìåíåíèÿ. Âû äåéñòâèòåëüíî õîòèòå çàêðûòü ôîðìó?",
"Ïðåäóïðåæäåíèå",
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning
);
if (result == DialogResult.No)
e.Cancel = true;
}
}
}

181
ClientRecordView/FormMain.Designer.cs generated Normal file
View File

@ -0,0 +1,181 @@
namespace ClientRecordView
{
partial class FormMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.клиентыToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.СозданиеToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.редToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.удалениеToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.отчетыToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ОтзывыToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ОтчетпоклиентамExcelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.отчетСДиаграммойToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.статусыToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.componentDocumentWithChartPieExcel = new ComponentsLibraryNet60.DocumentWithChart.ComponentDocumentWithChartPieExcel(this.components);
this.wordText = new WinFormsLibrary.NonVisualComponents.WordText(this.components);
this.controlDataTreeTable = new ControlsLibraryNet60.Data.ControlDataTreeTable();
this.userControlConfigurableTableDocument = new Components.Nonvisual.UserControlConfigurableTableDocument(this.components);
this.menuStrip.SuspendLayout();
this.SuspendLayout();
//
// menuStrip
//
this.menuStrip.ImageScalingSize = new System.Drawing.Size(24, 24);
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.клиентыToolStripMenuItem,
this.отчетыToolStripMenuItem,
this.статусыToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Size = new System.Drawing.Size(800, 33);
this.menuStrip.TabIndex = 0;
this.menuStrip.Text = "menuStrip";
//
// клиентыToolStripMenuItem
//
this.клиентыToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.СозданиеToolStripMenuItem,
this.редToolStripMenuItem,
this.удалениеToolStripMenuItem});
this.клиентыToolStripMenuItem.Name = "клиентыToolStripMenuItem";
this.клиентыToolStripMenuItem.Size = new System.Drawing.Size(96, 29);
this.клиентыToolStripMenuItem.Text = "Клиенты";
//
// СозданиеToolStripMenuItem
//
this.СозданиеToolStripMenuItem.Name = "СозданиеToolStripMenuItem";
this.СозданиеToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A)));
this.СозданиеToolStripMenuItem.Size = new System.Drawing.Size(311, 34);
this.СозданиеToolStripMenuItem.Text = "Создание";
this.СозданиеToolStripMenuItem.Click += new System.EventHandler(this.СозданиеToolStripMenuItem_Click);
//
// редToolStripMenuItem
//
this.редToolStripMenuItem.Name = "редToolStripMenuItem";
this.редToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.U)));
this.редToolStripMenuItem.Size = new System.Drawing.Size(311, 34);
this.редToolStripMenuItem.Text = "Редактирование";
this.редToolStripMenuItem.Click += new System.EventHandler(this.редToolStripMenuItem_Click);
//
// удалениеToolStripMenuItem
//
this.удалениеToolStripMenuItem.Name = "удалениеToolStripMenuItem";
this.удалениеToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.D)));
this.удалениеToolStripMenuItem.Size = new System.Drawing.Size(311, 34);
this.удалениеToolStripMenuItem.Text = "Удаление";
this.удалениеToolStripMenuItem.Click += new System.EventHandler(this.удалениеToolStripMenuItem_Click);
//
// отчетыToolStripMenuItem
//
this.отчетыToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.ОтзывыToolStripMenuItem,
this.ОтчетпоклиентамExcelToolStripMenuItem,
this.отчетСДиаграммойToolStripMenuItem});
this.отчетыToolStripMenuItem.Name = "отчетыToolStripMenuItem";
this.отчетыToolStripMenuItem.Size = new System.Drawing.Size(88, 29);
this.отчетыToolStripMenuItem.Text = "Отчеты";
//
// ОтзывыToolStripMenuItem
//
this.ОтзывыToolStripMenuItem.Name = "ОтзывыToolStripMenuItem";
this.ОтзывыToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
this.ОтзывыToolStripMenuItem.Size = new System.Drawing.Size(344, 34);
this.ОтзывыToolStripMenuItem.Text = "Отзывы о покупках";
this.ОтзывыToolStripMenuItem.Click += new System.EventHandler(this.ОтзывыToolStripMenuItem_Click);
//
// ОтчетпоклиентамExcelToolStripMenuItem
//
this.ОтчетпоклиентамExcelToolStripMenuItem.Name = "ОтчетпоклиентамExcelToolStripMenuItem";
this.ОтчетпоклиентамExcelToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.T)));
this.ОтчетпоклиентамExcelToolStripMenuItem.Size = new System.Drawing.Size(344, 34);
this.ОтчетпоклиентамExcelToolStripMenuItem.Text = "Отчет по клиентам";
this.ОтчетпоклиентамExcelToolStripMenuItem.Click += new System.EventHandler(this.ОтчетпоклиентамExcelToolStripMenuItem_Click);
//
// отчетСДиаграммойToolStripMenuItem
//
this.отчетСДиаграммойToolStripMenuItem.Name = "отчетСДиаграммойToolStripMenuItem";
this.отчетСДиаграммойToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
this.отчетСДиаграммойToolStripMenuItem.Size = new System.Drawing.Size(344, 34);
this.отчетСДиаграммойToolStripMenuItem.Text = "Отчет с диаграммой";
this.отчетСДиаграммойToolStripMenuItem.Click += new System.EventHandler(this.отчетСДиаграммойToolStripMenuItem_Click);
//
// статусыToolStripMenuItem
//
this.статусыToolStripMenuItem.Name = "статусыToolStripMenuItem";
this.статусыToolStripMenuItem.Size = new System.Drawing.Size(92, 29);
this.статусыToolStripMenuItem.Text = "Статусы";
this.статусыToolStripMenuItem.Click += new System.EventHandler(this.статусыToolStripMenuItem_Click);
//
// controlDataTreeTable
//
this.controlDataTreeTable.Dock = System.Windows.Forms.DockStyle.Fill;
this.controlDataTreeTable.Location = new System.Drawing.Point(0, 33);
this.controlDataTreeTable.Margin = new System.Windows.Forms.Padding(5, 6, 5, 6);
this.controlDataTreeTable.Name = "controlDataTreeTable";
this.controlDataTreeTable.Size = new System.Drawing.Size(800, 417);
this.controlDataTreeTable.TabIndex = 1;
//
// FormMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.controlDataTreeTable);
this.Controls.Add(this.menuStrip);
this.MainMenuStrip = this.menuStrip;
this.Name = "FormMain";
this.Text = "Основная форма";
this.Load += new System.EventHandler(this.FormMain_Load);
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private MenuStrip menuStrip;
private ToolStripMenuItem клиентыToolStripMenuItem;
private ToolStripMenuItem СозданиеToolStripMenuItem;
private ToolStripMenuItem редToolStripMenuItem;
private ToolStripMenuItem удалениеToolStripMenuItem;
private ToolStripMenuItem отчетыToolStripMenuItem;
private ToolStripMenuItem ОтзывыToolStripMenuItem;
private ToolStripMenuItem ОтчетпоклиентамExcelToolStripMenuItem;
private ToolStripMenuItem отчетСДиаграммойToolStripMenuItem;
private ToolStripMenuItem статусыToolStripMenuItem;
private ComponentsLibraryNet60.DocumentWithChart.ComponentDocumentWithChartPieExcel componentDocumentWithChartPieExcel;
private WinFormsLibrary.NonVisualComponents.WordText wordText;
private ControlsLibraryNet60.Data.ControlDataTreeTable controlDataTreeTable;
private Components.Nonvisual.UserControlConfigurableTableDocument userControlConfigurableTableDocument;
}
}

View File

@ -0,0 +1,219 @@
using ClientRecordContracts.BindingModels;
using ClientRecordContracts.BusinessLogicContracts;
using ClientRecordContracts.ViewModels;
using ComponentsLibraryNet60.DocumentWithTable;
using ComponentsLibraryNet60.Models;
using ControlsLibraryNet60.Data;
using ControlsLibraryNet60.Models;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Text;
using WinFormsLibrary.NonVisualComponents.Helpers;
namespace ClientRecordView
{
public partial class FormMain : Form
{
private readonly IClientLogic _logic;
public FormMain(IClientLogic clientLogic)
{
InitializeComponent();
_logic = clientLogic;
var nodeNames = new Queue<string>();
nodeNames.Enqueue("Status");
nodeNames.Enqueue("AmountString");
nodeNames.Enqueue("Id");
nodeNames.Enqueue("ClientFIO");
controlDataTreeTable.LoadConfig(new DataTreeNodeConfig { NodeNames = nodeNames});
}
private void LoadData()
{
controlDataTreeTable.Clear();
var clients = _logic.ReadList(null);
if (clients != null)
{
foreach (var client in clients)
{
client.AmountString = client.Amount?.ToString() ?? "Нет";
}
controlDataTreeTable.AddTable(clients);
}
}
private void СозданиеToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormClient));
if (service is FormClient form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void редToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormClient));
if (service is FormClient form)
{
var selected = controlDataTreeTable.GetSelectedObject<ClientViewModel>();
if (selected == null)
return;
form.Id = selected.Id;
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void удалениеToolStripMenuItem_Click(object sender, EventArgs e)
{
var selected = controlDataTreeTable.GetSelectedObject<ClientViewModel>();
if (selected == null)
return;
if (MessageBox.Show("Удалить запись?", "", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
if (_logic.Delete(new ClientBindingModel { Id = selected.Id }))
{
LoadData();
}
}
}
private void ОтзывыToolStripMenuItem_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog
{
Filter = "docx|*.docx"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
var clients = _logic.ReadList(null) ?? throw new Exception("Не удалось получить список клиентов");
List<string> paragraphs = new();
foreach (var client in clients)
{
if (client.Amount != null)
{
paragraphs.Add($"{client.ClientFIO}: {(string.IsNullOrWhiteSpace(client.ClientFIO) ? "Отзывы отсутствуют" : client.Reviews)}");
}
}
wordText.CreateWordText(new LongWordInfo()
{
Path = dialog.FileName,
Title = "Клиенты, совершашие покупки",
Paragraphs = paragraphs.ToArray()
});
MessageBox.Show("Готово!");
}
catch (Exception ex)
{
MessageBox.Show("Произошла ошибка: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void ОтчетпоклиентамExcelToolStripMenuItem_Click(object sender, EventArgs e)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
using var dialog = new SaveFileDialog
{
Filter = "PDF Files|*.pdf"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
var clients = _logic.ReadList(null) ?? throw new Exception("Не удалось получить список клиентов");
foreach (var client in clients)
{
client.AmountString = client.Amount?.ToString() ?? "нет";
}
userControlConfigurableTableDocument.SaveToDocument(
dialog.FileName,
"Учет клиентов",
new List<(double , string Header, string PropertyName)>
{
(1, "Id", "Id"),
(3, "ФИО", "ClientFIO"),
(2, "Статус", "Status"),
(3, "Сумма", "AmountString")
},
2,
2,
clients.OrderBy(x => x.Id).ToList()
);
MessageBox.Show("Готово!");
}
catch (Exception ex)
{
MessageBox.Show("Произошла ошибка: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void отчетСДиаграммойToolStripMenuItem_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog
{
Filter = "Excel Files|*.xlsx"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
var clients = _logic.ReadList(null) ?? throw new Exception("Не удалось получить список клиентов");
var statusMapping = new List<string>();
var data = new Dictionary<string, List<(int Date, double Value)>>
{
{
"Клиенты",
clients
.Where(x => x.Status != null)
.GroupBy(x => x.Status)
.Select((group, index) =>
{
statusMapping.Add($"{group.Key} - {index + 1}");
return (Date: index + 1, Value: (double)group.Count());
})
.ToList()
}
};
componentDocumentWithChartPieExcel.CreateDoc(new ComponentDocumentWithChartConfig
{
FilePath = dialog.FileName,
Header = $"Клиенты, совершавшие покупки, по статусам ({string.Join(", ", statusMapping)})",
ChartTitle = "Круговая диаграмма",
LegendLocation = ComponentsLibraryNet60.Models.Location.Bottom,
Data = data
});
MessageBox.Show("Готово!");
}
catch (Exception ex)
{
MessageBox.Show("Произошла ошибка: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void статусыToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormStatuses));
if (service is FormStatuses form)
{
form.ShowDialog();
}
}
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

@ -0,0 +1,75 @@
<root>
<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="menuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="componentDocumentWithChartPieExcel.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>302, 17</value>
</metadata>
<metadata name="wordText.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>295, 49</value>
</metadata>
<metadata name="userControlConfigurableTableDocument.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>424, 49</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>112</value>
</metadata>
</root>

View File

@ -0,0 +1,92 @@
namespace ClientRecordView
{
partial class FormStatuses
{
/// <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.dataGridView = new System.Windows.Forms.DataGridView();
this.NameCol = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Id = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();
this.SuspendLayout();
//
// dataGridView
//
this.dataGridView.BackgroundColor = System.Drawing.SystemColors.ControlLightLight;
this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.NameCol,
this.Id});
this.dataGridView.Dock = System.Windows.Forms.DockStyle.Fill;
this.dataGridView.Location = new System.Drawing.Point(0, 0);
this.dataGridView.Margin = new System.Windows.Forms.Padding(4);
this.dataGridView.Name = "dataGridView";
this.dataGridView.RowHeadersWidth = 51;
this.dataGridView.RowTemplate.Height = 29;
this.dataGridView.Size = new System.Drawing.Size(800, 450);
this.dataGridView.TabIndex = 1;
this.dataGridView.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellValueChanged);
this.dataGridView.UserDeletingRow += new System.Windows.Forms.DataGridViewRowCancelEventHandler(this.dataGridView_UserDeletingRow);
this.dataGridView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.dataGridView_KeyDown);
this.dataGridView.KeyUp += new System.Windows.Forms.KeyEventHandler(this.dataGridView_KeyUp);
//
// NameCol
//
this.NameCol.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.NameCol.HeaderText = "Название";
this.NameCol.MinimumWidth = 6;
this.NameCol.Name = "NameCol";
//
// Id
//
this.Id.HeaderText = "Id";
this.Id.MinimumWidth = 6;
this.Id.Name = "Id";
this.Id.Visible = false;
this.Id.Width = 6;
//
// FormStatuses
//
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.dataGridView);
this.Name = "FormStatuses";
this.Text = "Статусы";
this.Load += new System.EventHandler(this.FormStatuses_Load);
((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();
this.ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private DataGridViewTextBoxColumn NameCol;
private DataGridViewTextBoxColumn Id;
}
}

View File

@ -0,0 +1,109 @@
using ClientRecordContracts.BindingModels;
using ClientRecordContracts.BusinessLogicContracts;
using ClientRecordContracts.SearchModels;
namespace ClientRecordView
{
public partial class FormStatuses : Form
{
private readonly IStatusLogic _logic;
private bool dataLoading = false;
public FormStatuses(IStatusLogic statusLogic)
{
InitializeComponent();
_logic = statusLogic;
}
private void FormStatuses_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
dataLoading = true;
try
{
var list = _logic.ReadList(null);
if (list != null)
{
foreach (var role in list)
{
int rowIndex = dataGridView.Rows.Add();
dataGridView.Rows[rowIndex].Cells[0].Value = role.Name;
dataGridView.Rows[rowIndex].Cells[1].Value = role.Id;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
dataLoading = false;
}
}
private void dataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (dataLoading || e.RowIndex < 0 || e.ColumnIndex != 0)
return;
if (dataGridView.Rows[e.RowIndex].Cells[1].Value != null)
{
var name = dataGridView.Rows[e.RowIndex].Cells[0].Value?.ToString()
?? throw new Exception("Не заполнено название статуса");
_logic.Update(new StatusBindingModel { Id = Convert.ToInt32(dataGridView.Rows[e.RowIndex].Cells[1].Value), Name = name });
}
else
{
var name = dataGridView.Rows[e.RowIndex].Cells[0].Value?.ToString()
?? throw new Exception("Не заполнено название статуса");
_logic.Create(new StatusBindingModel { Id = 0, Name = name });
var list = _logic.ReadList(null) ?? throw new Exception("Не удалось получить список статусов");
int newRoleId = list.Last().Id;
dataGridView.Rows[e.RowIndex].Cells[1].Value = newRoleId;
}
}
private void dataGridView_KeyUp(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Insert:
dataGridView.Rows.Add();
break;
}
}
private void DeleteRows(DataGridViewSelectedRowCollection rows)
{
for (int i = 0; i < rows.Count; i++)
{
DataGridViewRow row = rows[i];
if (row.IsNewRow)
continue;
if (row.Cells[1].Value != null && !_logic.Delete(new StatusBindingModel { Id = Convert.ToInt32(row.Cells[1].Value), Name = row.Cells[0].Value?.ToString() }))
throw new Exception($"Ошибка удаления строки: {row.Cells[0].Value}");
dataGridView.Rows.Remove(row);
}
}
private void dataGridView_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
{
e.Cancel = true;
if (dataGridView.SelectedRows == null)
return;
if (MessageBox.Show("Удалить записи?", "Подтвердите действие", MessageBoxButtons.YesNo) == DialogResult.No)
return;
DeleteRows(dataGridView.SelectedRows);
}
private void dataGridView_KeyDown(object sender, KeyEventArgs e)
{
}
}
}

View File

@ -0,0 +1,63 @@
<root>
<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="Id.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@ -0,0 +1,216 @@
using ClientRecordBuisinessLogic.BuisinessLogic;
using ClientRecordContracts.BindingModels;
using ClientRecordContracts.BusinessLogicContracts;
using ClientRecordContracts.ViewModels;
using ClientRecordDatabaseImplement.Implements;
using Components.Nonvisual;
using ComponentsLibraryNet60.Models;
using ControlsLibraryNet60.Data;
using ControlsLibraryNet60.Models;
using PluginsConventionLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WinFormsLibrary.NonVisualComponents.Helpers;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
namespace ClientRecordView
{
public class PluginsConvention : IPluginsConvention
{
private readonly IClientLogic _clientLogic;
private readonly IStatusLogic _statusLogic;
private readonly ControlDataTreeTable _controlDataTreeTable = new();
private readonly WinFormsLibrary.NonVisualComponents.WordText _wordText = new();
private readonly Components.Nonvisual.UserControlConfigurableTableDocument _componentDocumentWithTableMultiHeaderPdf = new();
private readonly ComponentsLibraryNet60.DocumentWithChart.ComponentDocumentWithChartPieExcel _componentDocumentWithChartPieExcel = new();
public PluginsConvention()
{
_clientLogic = new ClientLogic(new ClientStorage());
_statusLogic = new StatusLogic(new StatusStorage());
ReloadData();
}
public string PluginName => "LabWork3 Plugin";
public UserControl GetControl => _controlDataTreeTable;
public PluginsConventionElement GetElement
{
get
{
var selected = _controlDataTreeTable.GetSelectedObject<ClientViewModel>()
?? throw new Exception("Не удалось получить выбранный элемент");
return new PluginsConventionClient()
{
Id = IntToGuid(selected.Id),
ClientFIO= selected.ClientFIO,
Amount= selected.AmountString,
Reviews= selected.Reviews,
Status= selected.Status,
};
}
}
public Form GetForm(PluginsConventionElement element)
{
var formClient = new FormClient(_clientLogic, _statusLogic);
if (element != null)
{
formClient.Id = element.Id.GetHashCode();
}
return formClient;
}
public Form GetThesaurus()
{
return new FormStatuses(_statusLogic);
}
public bool DeleteElement(PluginsConventionElement element)
{
return _clientLogic.Delete(
new ClientBindingModel { Id = element.Id.GetHashCode() }
);
}
public void ReloadData()
{
try
{
var clients = _clientLogic.ReadList(null) ?? throw new Exception("Не удалось получить список аккаунтов");
_controlDataTreeTable.Clear();
var nodeNames = new Queue<string>();
nodeNames.Enqueue("Status");
nodeNames.Enqueue("AmountString");
nodeNames.Enqueue("Id");
nodeNames.Enqueue("ClientFIO");
_controlDataTreeTable.LoadConfig(new DataTreeNodeConfig { NodeNames = nodeNames });
foreach (var client in clients)
{
client.AmountString = client.Amount?.ToString() ?? "Нет";
}
_controlDataTreeTable.AddTable(clients);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public bool CreateSimpleDocument(PluginsConventionSaveDocument saveDocument)
{
try
{
var clients = _clientLogic.ReadList(null) ?? throw new Exception("Не удалось получить список аккаунтов");
List<string> paragraphs = new();
foreach (var client in clients)
{
if (client.Amount != null)
{
paragraphs.Add($"{client.ClientFIO}: {(string.IsNullOrWhiteSpace(client.Reviews) ? "Отзывы отсутствуют" : client.Reviews)}");
}
}
_wordText.CreateWordText(new LongWordInfo()
{
Path = saveDocument.FileName,
Title = "Клиенты с покупками",
Paragraphs = paragraphs.ToArray()
});
return true;
}
catch (Exception)
{
return false;
}
}
public bool CreateTableDocument(PluginsConventionSaveDocument saveDocument)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
try
{
var clients = _clientLogic.ReadList(null) ?? throw new Exception("Не удалось получить список клиентов");
foreach (var client in clients)
{
client.AmountString = client.Amount?.ToString() ?? "нет";
}
_componentDocumentWithTableMultiHeaderPdf.SaveToDocument(
saveDocument.FileName,
"Учет клиентов",
new List<(double, string Header, string PropertyName)>
{
(1, "Id", "Id"),
(3, "ФИО", "ClientFIO"),
(2, "Статус", "Status"),
(3, "Сумма", "AmountString")
},
2,
2,
clients.OrderBy(x => x.Id).ToList()
);
return true;
}
catch (Exception)
{
return false;
}
}
public bool CreateChartDocument(PluginsConventionSaveDocument saveDocument)
{
try
{
var clients = _clientLogic.ReadList(null) ?? throw new Exception("Не удалось получить список клиентов");
var roleMapping = new List<string>();
var data = new Dictionary<string, List<(int Date, double Value)>>
{
{
"Клиенты",
clients
.Where(x => x.Amount != null)
.GroupBy(x => x.Status)
.Select((group, index) =>
{
roleMapping.Add($"{group.Key} - {index + 1}");
return (Date: index + 1, Value: (double)group.Count());
})
.ToList()
}
};
_componentDocumentWithChartPieExcel.CreateDoc(new ComponentDocumentWithChartConfig
{
FilePath = saveDocument.FileName,
Header = $"Клиенты с покупками по статусам ({string.Join(", ", roleMapping)})",
ChartTitle = "Круговая диаграмма",
LegendLocation = Location.Bottom,
Data = data
});
return true;
}
catch (Exception)
{
return false;
}
}
private Guid IntToGuid(int value)
{
byte[] bytes = new byte[16];
BitConverter.GetBytes(value).CopyTo(bytes, 0);
return new Guid(bytes);
}
}
}

View File

@ -0,0 +1,13 @@
using PluginsConventionLibrary;
namespace ClientRecordView
{
internal class PluginsConventionClient : PluginsConventionElement
{
public string? Reviews { get; set; }
public string ClientFIO { get; set; } = string.Empty;
public string? Amount { get; set; }
public string Status { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,41 @@
using ClientRecordBuisinessLogic.BuisinessLogic;
using ClientRecordContracts.BusinessLogicContracts;
using ClientRecordContracts.StoragesContracts;
using ClientRecordDatabaseImplement.Implements;
using Microsoft.Extensions.DependencyInjection;
namespace ClientRecordView
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
private static ServiceProvider? _serviceProvider;
public static ServiceProvider? ServiceProvider => _serviceProvider;
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
}
private static void ConfigureServices(ServiceCollection services)
{
services.AddTransient<IStatusStorage, StatusStorage>();
services.AddTransient<IClientStorage, ClientStorage>();
services.AddTransient<IStatusLogic, StatusLogic>();
services.AddTransient<IClientLogic, ClientLogic>();
services.AddTransient<FormMain>();
services.AddTransient<FormClient>();
services.AddTransient<FormStatuses>();
}
}
}

View File

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

View File

@ -0,0 +1,7 @@
namespace PluginsConventionLibrary
{
public class PluginsConventionElement
{
public Guid Id { get; set; }
}
}

View File

@ -0,0 +1,7 @@
namespace PluginsConventionLibrary
{
public class PluginsConventionSaveDocument
{
public string FileName { get; set; }
}
}

View File

@ -1,2 +1 @@
# PIbd-21_RazubaevSM_PlumbingRepair_Base
# PIbd-31_RazubaevSM_COP_10

View File

@ -3,9 +3,23 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33110.190
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinFormsLibrary", "WinFormsLibrary\WinFormsLibrary.csproj", "{FA2C000C-0815-44C4-BBA7-FB37C33DE121}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinFormsLibraryRazubaev", "WinFormsLibrary\WinFormsLibraryRazubaev.csproj", "{FA2C000C-0815-44C4-BBA7-FB37C33DE121}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinForms", "WinForms\WinForms.csproj", "{AA566691-FB51-4E4C-BB7B-9BA77AD20FD1}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientRecordDataModels", "ClientRecordDataModels\ClientRecordDataModels.csproj", "{A7D71AAC-2AEE-4878-81DE-72429FBBA93B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientRecordContracts", "ClientRecordContracts\ClientRecordContracts.csproj", "{B641C70B-17E3-454A-8749-E8D54928E733}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientRecordBuisinessLogic", "ClientRecordBuisinessLogic\ClientRecordBuisinessLogic.csproj", "{56768B0F-B9C4-48E5-AAC4-E82514B64BD8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientRecordDatabaseImplement", "ClientRecordDatabaseImplement\ClientRecordDatabaseImplement.csproj", "{3272666F-969A-4350-8A71-C70CF2F13527}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientRecordView", "ClientRecordView\ClientRecordView.csproj", "{F6A250F2-C027-4DA9-AABC-3C69C153F58B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinForms", "WinForms\WinForms.csproj", "{CA2C31AC-090D-45CB-B6F2-292B8F823438}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginConventionLibrary", "PluginConventionLibrary\PluginConventionLibrary.csproj", "{EEF969D3-121B-48D2-B88D-CC2F5DD42A4A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsFormAppPlugin", "WindowsFormAppPlugin\WindowsFormAppPlugin.csproj", "{967D9E94-166F-47B5-8C9B-61AE9961C491}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -17,10 +31,38 @@ Global
{FA2C000C-0815-44C4-BBA7-FB37C33DE121}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA2C000C-0815-44C4-BBA7-FB37C33DE121}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA2C000C-0815-44C4-BBA7-FB37C33DE121}.Release|Any CPU.Build.0 = Release|Any CPU
{AA566691-FB51-4E4C-BB7B-9BA77AD20FD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA566691-FB51-4E4C-BB7B-9BA77AD20FD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA566691-FB51-4E4C-BB7B-9BA77AD20FD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA566691-FB51-4E4C-BB7B-9BA77AD20FD1}.Release|Any CPU.Build.0 = Release|Any CPU
{A7D71AAC-2AEE-4878-81DE-72429FBBA93B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A7D71AAC-2AEE-4878-81DE-72429FBBA93B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7D71AAC-2AEE-4878-81DE-72429FBBA93B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7D71AAC-2AEE-4878-81DE-72429FBBA93B}.Release|Any CPU.Build.0 = Release|Any CPU
{B641C70B-17E3-454A-8749-E8D54928E733}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B641C70B-17E3-454A-8749-E8D54928E733}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B641C70B-17E3-454A-8749-E8D54928E733}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B641C70B-17E3-454A-8749-E8D54928E733}.Release|Any CPU.Build.0 = Release|Any CPU
{56768B0F-B9C4-48E5-AAC4-E82514B64BD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{56768B0F-B9C4-48E5-AAC4-E82514B64BD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{56768B0F-B9C4-48E5-AAC4-E82514B64BD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{56768B0F-B9C4-48E5-AAC4-E82514B64BD8}.Release|Any CPU.Build.0 = Release|Any CPU
{3272666F-969A-4350-8A71-C70CF2F13527}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3272666F-969A-4350-8A71-C70CF2F13527}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3272666F-969A-4350-8A71-C70CF2F13527}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3272666F-969A-4350-8A71-C70CF2F13527}.Release|Any CPU.Build.0 = Release|Any CPU
{F6A250F2-C027-4DA9-AABC-3C69C153F58B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F6A250F2-C027-4DA9-AABC-3C69C153F58B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F6A250F2-C027-4DA9-AABC-3C69C153F58B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F6A250F2-C027-4DA9-AABC-3C69C153F58B}.Release|Any CPU.Build.0 = Release|Any CPU
{CA2C31AC-090D-45CB-B6F2-292B8F823438}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CA2C31AC-090D-45CB-B6F2-292B8F823438}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CA2C31AC-090D-45CB-B6F2-292B8F823438}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CA2C31AC-090D-45CB-B6F2-292B8F823438}.Release|Any CPU.Build.0 = Release|Any CPU
{EEF969D3-121B-48D2-B88D-CC2F5DD42A4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EEF969D3-121B-48D2-B88D-CC2F5DD42A4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EEF969D3-121B-48D2-B88D-CC2F5DD42A4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EEF969D3-121B-48D2-B88D-CC2F5DD42A4A}.Release|Any CPU.Build.0 = Release|Any CPU
{967D9E94-166F-47B5-8C9B-61AE9961C491}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{967D9E94-166F-47B5-8C9B-61AE9961C491}.Debug|Any CPU.Build.0 = Debug|Any CPU
{967D9E94-166F-47B5-8C9B-61AE9961C491}.Release|Any CPU.ActiveCfg = Release|Any CPU
{967D9E94-166F-47B5-8C9B-61AE9961C491}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -28,6 +28,7 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.dropDownList = new WinFormsLibrary.DropDownList();
this.buttonAdd = new System.Windows.Forms.Button();
this.buttonClear = new System.Windows.Forms.Button();
@ -42,6 +43,14 @@
this.buttonAddValues = new System.Windows.Forms.Button();
this.buttonShowItem = new System.Windows.Forms.Button();
this.labelShowInput = new System.Windows.Forms.Label();
this.panel1 = new System.Windows.Forms.Panel();
this.buttonWordDiagram = new System.Windows.Forms.Button();
this.buttonWordTable = new System.Windows.Forms.Button();
this.buttonWordText = new System.Windows.Forms.Button();
this.wordTextComponent = new WinFormsLibrary.NonVisualComponents.WordText(this.components);
this.wordTableComponent = new WinFormsLibrary.NonVisualComponents.WordTable(this.components);
this.wordDiagramComponent = new WinFormsLibrary.NonVisualComponents.WordDiagram(this.components);
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// dropDownList
@ -140,7 +149,7 @@
this.listBoxValues.Location = new System.Drawing.Point(437, 30);
this.listBoxValues.Name = "listBoxValues";
this.listBoxValues.SelectedIndex = -1;
this.listBoxValues.Size = new System.Drawing.Size(594, 237);
this.listBoxValues.Size = new System.Drawing.Size(895, 237);
this.listBoxValues.TabIndex = 10;
//
// buttonAddValues
@ -172,11 +181,58 @@
this.labelShowInput.TabIndex = 13;
this.labelShowInput.Text = "Для проверки";
//
// panel1
//
this.panel1.BackColor = System.Drawing.Color.White;
this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panel1.Controls.Add(this.buttonWordDiagram);
this.panel1.Controls.Add(this.buttonWordTable);
this.panel1.Controls.Add(this.buttonWordText);
this.panel1.Location = new System.Drawing.Point(13, 404);
this.panel1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(1021, 165);
this.panel1.TabIndex = 14;
//
// buttonWordDiagram
//
this.buttonWordDiagram.Location = new System.Drawing.Point(753, 48);
this.buttonWordDiagram.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.buttonWordDiagram.Name = "buttonWordDiagram";
this.buttonWordDiagram.Size = new System.Drawing.Size(193, 57);
this.buttonWordDiagram.TabIndex = 15;
this.buttonWordDiagram.Text = "Word (диаграмма)";
this.buttonWordDiagram.UseVisualStyleBackColor = true;
this.buttonWordDiagram.Click += new System.EventHandler(this.buttonWordDiagram_Click);
//
// buttonWordTable
//
this.buttonWordTable.Location = new System.Drawing.Point(423, 48);
this.buttonWordTable.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.buttonWordTable.Name = "buttonWordTable";
this.buttonWordTable.Size = new System.Drawing.Size(193, 57);
this.buttonWordTable.TabIndex = 14;
this.buttonWordTable.Text = "Word (таблица)";
this.buttonWordTable.UseVisualStyleBackColor = true;
this.buttonWordTable.Click += new System.EventHandler(this.buttonWordTable_Click);
//
// buttonWordText
//
this.buttonWordText.Location = new System.Drawing.Point(67, 48);
this.buttonWordText.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.buttonWordText.Name = "buttonWordText";
this.buttonWordText.Size = new System.Drawing.Size(193, 57);
this.buttonWordText.TabIndex = 13;
this.buttonWordText.Text = "Word (текст)";
this.buttonWordText.UseVisualStyleBackColor = true;
this.buttonWordText.Click += new System.EventHandler(this.buttonWordText_Click);
//
// FormComponents
//
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1067, 450);
this.ClientSize = new System.Drawing.Size(1344, 630);
this.Controls.Add(this.panel1);
this.Controls.Add(this.labelShowInput);
this.Controls.Add(this.buttonShowItem);
this.Controls.Add(this.buttonAddValues);
@ -193,6 +249,7 @@
this.Controls.Add(this.dropDownList);
this.Name = "FormComponents";
this.Text = "Form1";
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
@ -214,5 +271,12 @@
private Button buttonAddValues;
private Button buttonShowItem;
private Label labelShowInput;
private Panel panel1;
private Button buttonWordDiagram;
private Button buttonWordTable;
private Button buttonWordText;
private WinFormsLibrary.NonVisualComponents.WordText wordTextComponent;
private WinFormsLibrary.NonVisualComponents.WordTable wordTableComponent;
private WinFormsLibrary.NonVisualComponents.WordDiagram wordDiagramComponent;
}
}

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using WinFormsLibrary;
using WinFormsLibrary.NonVisualComponents.Enums;
using WinFormsLibrary.NonVisualComponents.Helpers;
using WinFormsLibrary.Object;
namespace WinForms
@ -11,18 +13,19 @@ namespace WinForms
public FormComponents()
{
list = new List<string>();
list.AddRange(new string[] { "привет", "пока", "бб" });
Client client1 = new Client("Сергей", "нет", "Идиот", 3);
Client client2 = new Client("Давид", "да-11", "Гений", 1);
Client client3 = new Client("Руслан", "Асу", "Летальный", 4);
list.AddRange(new string[] { "Пример1", ример2", ример3" });
Client client1 = new Client("Разубаев Сергей Михайлович", "Товар понравился", "Пользователь", 300);
Client client2 = new Client("Макаров Давид Вячеславович", "Вместо товара пришла коробка", "Подписчик", 100);
Client client3 = new Client("Анисин Руслан Сергеевич", "Товар не понравился", "ПОльзователь", 234);
clients.Add(client1);
clients.Add(client2);
clients.Add(client3);
InitializeComponent();
dropDownList.LoadValues(new List<string>() { "чего", "забей", "пример" });
dropDownList.LoadValues(new List<string>() { "пример", "пример", "пример" });
emailTextBox.Pattern = @"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$";
listBoxValues.SetLayout("ФИО [FIO] Обзор [Review] Статус [Status] сумма [Sum]", "[", "]");
listBoxValues.SetLayout("ФИО [FIO] Обзор [Review] Статус [Status] сумма [Sum].", '[', ']');
dropDownList.ValueChanged += CustomEventHandler;
listBoxValues.AddItems<Client>(clients);
}
private void CustomEventHandler(object sender, EventArgs e)
{
@ -75,7 +78,142 @@ namespace WinForms
private void buttonAddValues_Click(object sender, EventArgs e)
{
listBoxValues.AddInListBox<Client>(clients);
listBoxValues.AddItems<Client>(clients);
}
private void buttonWordText_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog
{
Filter = "docx|*.docx"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
wordTextComponent.CreateWordText(new LongWordInfo()
{
Path = dialog.FileName,
Title = "I. Глиняный ужас",
Paragraphs = new string[] { "По мне, неспособность человеческого разума соотнести между собою все, что только вмещает в себя наш мир, это великая милость. Мы живем на безмятежном островке неведения посреди черных морей бесконечности, и дальние плавания нам заказаны. Науки, трудясь каждая в своем направлении, до сих пор особого вреда нам не причиняли. Но в один прекрасный день разобщенные познания будут сведены воедино, и перед нами откроются такие ужасающие горизонты реальности, равно как и наше собственное страшное положение, что мы либо сойдем с ума от этого откровения, либо бежим от смертоносного света в мир и покой нового темного средневековья.",
"Теософы уже предугадали устрашающее величие космического цикла, в пределах которого и наш мир, и весь род человеческий не более чем преходящая случайность. Они намекают на странных пришельцев из тьмы веков в выражениях, от которых кровь бы застыла в жилах, когда бы не личина утешительного оптимизма. Но не от них явился тот один-единственный отблеск запретных эпох, что леденит мне кровь наяву и сводит с ума во сне. Это мимолетное впечатление, как и все страшные намеки на правду, родилось из случайной комбинации разрозненных фрагментов в данном случае, вырезки из старой газеты и записей покойного профессора. Надеюсь, никому больше не придет в голову их сопоставить; сам я, если останусь жив, ни за что не стану сознательно восполнять звенья в столь чудовищной цепи. Думается мне, что и профессор тоже намеревался сохранить в тайне известную ему часть и непременно уничтожил бы свои заметки, если бы не внезапная смерть.",
"Как наследнику и душеприказчику моего двоюродного деда ибо он умер бездетным вдовцом, мне полагалось сколь возможно тщательно просмотреть его архивы; с этой целью я перевез все его коробки и папки на свою бостонскую квартиру. Большую часть разобранных мною материалов со временем опубликует Американское археологическое общество, однако ж среди ящиков нашелся один, изрядно меня озадачивший: вот его-то мне особенно не хотелось показывать чужим. Ящик был заперт, ключа нигде не оказалось; но в конце концов я догадался осмотреть брелок, что профессор всегда носил в кармане. И действительно: открыть замок мне удалось, но тут передо мною воздвиглось препятствие еще более серьезное и непреодолимое. Что, ради всего святого, означали странный глиняный барельеф и разрозненные записи, наброски и газетные вырезки, мною обнаруженные? Или дед мой, на закате дней своих, стал жертвой самого банального надувательства? Я решил непременно разыскать эксцентричного скульптора, по всей видимости, нарушившего душевный покой старика."}
});
MessageBox.Show("Готово!");
}
catch (Exception ex)
{
MessageBox.Show("Произошла ошибка: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void buttonWordTable_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog
{
Filter = "docx|*.docx"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
var columns = new List<ColumnInfo>
{
new() { FirstRowHeader = "Идент", PropertyName = "Id", Width = 1.3 },
new() { FirstRowHeader = "Статус", PropertyName = "Status", Width = 1.3 },
new() { FirstRowHeader = "Личные данные", SecondRowHeader = "Имя", PropertyName = "FirstName", Width = 1.7 },
new() { FirstRowHeader = "Личные данные", SecondRowHeader = "Фамилия", PropertyName = "LastName", Width = 1.7 },
new() { FirstRowHeader = "Личные данные", SecondRowHeader = "Возраст", PropertyName = "Age", Width = 1.7 },
new() { FirstRowHeader = "Дети", PropertyName = "Children", Width = 1.3 },
new() { FirstRowHeader = "Машина", PropertyName = "Car", Width = 1.7 },
new() { FirstRowHeader = "Работа", SecondRowHeader = "Подразделение", PropertyName = "Department", Width = 2.4 },
new() { FirstRowHeader = "Работа", SecondRowHeader = "Должность", PropertyName = "Position", Width = 2.4 },
new() { FirstRowHeader = "Премия", PropertyName = "Bonus", Width = 2 }
};
var employees = new List<Example>
{
new() { Id = 1, Status = "нет", FirstName = "Иван", LastName = "Иванов", Age = 34, Children = "нет", Car = "есть", Department = "Департамент 1", Position = "Инженер", Bonus = 2000.1 },
new() { Id = 2, Status = "нет", FirstName = "Петр", LastName = "Петров", Age = 44, Children = "есть", Car = "есть", Department = "Департамент 1", Position = "Инженер", Bonus = 2000.1 },
new() { Id = 3, Status = "да", FirstName = "Сергей", LastName = "Сергеев", Age = 55, Children = "нет", Car = "нет", Department = "Департамент 1", Position = "Руководитель", Bonus = 5000.5 },
new() { Id = 4, Status = "нет", FirstName = "Ольга", LastName = "Иванова", Age = 34, Children = "есть", Car = "нет", Department = "Бухгалтерия", Position = "Бухгалтер", Bonus = 2000.1 },
new() { Id = 5, Status = "да", FirstName = "Татьяна", LastName = "Петрова", Age = 44, Children = "нет", Car = "нет", Department = "Бухгалтерия", Position = "Старший бухгалтер", Bonus = 7000.6 }
};
var mergedColumns = new List<(int, int)>
{
(2, 4),
(7, 8)
};
var tableInfo = new WordTableInfo<Example>
{
Path = dialog.FileName,
Title = "Заголовок",
ColumnInfos = columns,
Items = employees,
MergedColumns = mergedColumns
};
wordTableComponent.CreateTable(tableInfo);
MessageBox.Show("Готово!");
}
catch (Exception ex)
{
MessageBox.Show("Произошла ошибка: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void buttonWordDiagram_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog
{
Filter = "docx|*.docx"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
var series = new List<SeriesParameters>
{
new() {
SeriesName = "Номер 1",
ValuesY = new List<double> { 14, 22, 13 },
Color = Color.FromArgb(255, 165, 0)
},
new() {
SeriesName = "Номер 2",
ValuesY = new List<double> { 87, 44, 51 },
Color = Color.FromArgb(145, 145, 145)
},
new() {
SeriesName = "Номер 3",
ValuesY = new List<double> { 29, 15, 7 },
Color = Color.FromArgb(255, 255, 0)
}
};
wordDiagramComponent.CreateDiagramDocument(new GraphicWordInfo()
{
Path = dialog.FileName,
DocumentTitle = "Диаграмма в ворде",
DiagramTitle = "Ниже показана диаграмма об исследовании...",
LegendLayout = LegendLayoutEnum.Bottom,
SeriesX = new List<string> { "Пример", "Пример", "Пример" },
SeriesParameters = series
});
MessageBox.Show("Готово!");
}
catch (Exception ex)
{
MessageBox.Show("Произошла ошибка: " + ex.Message, "А", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
}

View File

@ -57,4 +57,13 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="wordTextComponent.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="wordTableComponent.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>156, 17</value>
</metadata>
<metadata name="wordDiagramComponent.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>392, 17</value>
</metadata>
</root>

View File

@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\WinFormsLibrary\WinFormsLibrary.csproj" />
<ProjectReference Include="..\WinFormsLibrary\WinFormsLibraryRazubaev.csproj" />
</ItemGroup>
</Project>

View File

@ -1,94 +0,0 @@
using System.Text;
namespace WinFormsLibrary
{
public partial class ListBoxValues : UserControl
{
private string _layout;
private string _endSymbol;
private string _startSymbol;
public ListBoxValues()
{
InitializeComponent();
}
public void SetLayout(string layout, string startSymbol, string endSymbol)
{
if (layout == null || startSymbol == null || endSymbol == null)
{
return;
}
_layout = layout;
_endSymbol = endSymbol;
_startSymbol = startSymbol;
}
public int SelectedIndex
{
get
{
if (listBoxObjects.SelectedIndex == -1)
{
return -1;
}
return listBoxObjects.SelectedIndex;
}
set
{
if (listBoxObjects.SelectedItems.Count != 0)
{
listBoxObjects.SelectedIndex = value;
}
}
}
public T GetObjectFromStr<T>() where T : class, new()
{
string selectedString = "";
if (listBoxObjects.SelectedIndex != -1)
{
selectedString = listBoxObjects.SelectedItem.ToString();
}
T curObject = new T();
foreach (var pr in typeof(T).GetProperties())
{
if (!pr.CanWrite)
{
continue;
}
int borderOne = selectedString.IndexOf(_startSymbol);
StringBuilder sb = new StringBuilder(selectedString);
selectedString = sb.ToString();
int borderTwo = selectedString.IndexOf(_endSymbol);
if (borderOne == -1 || borderTwo == -1) break;
string propertyValue = selectedString.Substring(borderOne + 1, borderTwo - borderOne-1);
selectedString = selectedString.Substring(borderTwo + 1);
pr.SetValue(curObject, Convert.ChangeType(propertyValue, pr.PropertyType));
}
return curObject;
}
public void AddInListBox<T>(List<T> values)
{
if (_layout == null || _startSymbol == null || _endSymbol == null)
{
MessageBox.Show("заполните информацию о макетной строке");
return;
}
if (!_layout.Contains(_startSymbol) || !_layout.Contains(_endSymbol))
{
MessageBox.Show("Макетная строка не содержит нужные элементы");
return;
}
foreach (var item in values)
{
string str = _layout;
foreach (var prop in item.GetType().GetProperties())
{
string str1 = $"{_startSymbol}" + $"{prop.Name}" + $"{_endSymbol}";
str = str.Replace(str1, $"{_startSymbol}" + prop.GetValue(item).ToString() + $"{_endSymbol}");
}
listBoxObjects.Items.Add(str);
}
}
}
}

View File

@ -0,0 +1,16 @@
namespace WinFormsLibrary.NonVisualComponents.Enums
{
public enum LegendLayoutEnum
{
None,
Left,
Top,
Right,
Bottom
}
}

View File

@ -0,0 +1,14 @@
namespace WinFormsLibrary.NonVisualComponents.Helpers
{
public class ColumnInfo
{
public string FirstRowHeader { get; set; } = string.Empty;
public string SecondRowHeader { get; set; } = string.Empty;
public string PropertyName { get; set; } = string.Empty;
public double Width { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using WinFormsLibrary.NonVisualComponents.Enums;
namespace WinFormsLibrary.NonVisualComponents.Helpers
{
public class GraphicWordInfo
{
public string Path { get; set; } = string.Empty;
public string DocumentTitle { get; set; } = string.Empty;
public string DiagramTitle { get; set; } = string.Empty;
public LegendLayoutEnum LegendLayout { get; set; }
public List<string> SeriesX { get; set; }
public List<SeriesParameters> SeriesParameters { get; set; } = new();
}
}

View File

@ -0,0 +1,11 @@
namespace WinFormsLibrary.NonVisualComponents.Helpers
{
public class LongWordInfo
{
public string Path { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public string[] Paragraphs { get; set; } = Array.Empty<string>();
}
}

View File

@ -0,0 +1,12 @@
namespace WinFormsLibrary.NonVisualComponents.Helpers
{
public class SeriesParameters
{
public string SeriesName { get; set; } = string.Empty;
public List<double> ValuesY { get; set; } = new();
public Color Color { get; set; }
}
}

View File

@ -0,0 +1,14 @@
namespace WinFormsLibrary.NonVisualComponents.Helpers
{
public class WordTableInfo<T>
{
public string Path { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<ColumnInfo> ColumnInfos { get; set; } = new();
public List<T> Items { get; set; } = new();
public List<(int, int)> MergedColumns { get; set; } = new();
}
}

View File

@ -0,0 +1,36 @@
namespace WinFormsLibrary.NonVisualComponents
{
partial class WordDiagram
{
/// <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.ComponentModel;
using Word = Microsoft.Office.Interop.Word;
using Excel = Microsoft.Office.Interop.Excel;
using WinFormsLibrary.NonVisualComponents.Helpers;
using WinFormsLibrary.NonVisualComponents.Enums;
namespace WinFormsLibrary.NonVisualComponents
{
public partial class WordDiagram : Component
{
public WordDiagram()
{
InitializeComponent();
}
public WordDiagram(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public void CreateDiagramDocument(GraphicWordInfo diagramInfo)
{
ValidateDiagramInfo(diagramInfo);
var wordApp = new Word.Application();
var document = wordApp.Documents.Add();
var paragraph = document.Paragraphs.Add();
paragraph.Range.Text = diagramInfo.DocumentTitle;
paragraph.Range.Font.Size = 24;
paragraph.Range.Font.Bold = 1;
paragraph.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
paragraph.Range.InsertParagraphAfter();
AddChart(document, diagramInfo);
document.SaveAs2(diagramInfo.Path);
wordApp.Quit();
}
private void AddChart(Word.Document document, GraphicWordInfo diagramInfo)
{
var paragraph = document.Paragraphs.Add();
var chartShape = document.InlineShapes.AddChart2(-1, (Microsoft.Office.Core.XlChartType)Excel.XlChartType.xlLine, paragraph.Range);
var chart = chartShape.Chart;
chart.HasTitle = true;
chart.ChartTitle.Text = diagramInfo.DiagramTitle;
var chartSeriesCollection = chart.SeriesCollection();
for (int i = chartSeriesCollection.Count; i >= 1; i--)
{
chartSeriesCollection.Item(i).Delete();
}
var seriesX = diagramInfo.SeriesX.ToArray();
for (int i = 0; i < diagramInfo.SeriesParameters.Count; i++)
{
var seriesInfo = diagramInfo.SeriesParameters[i];
var series = chartSeriesCollection.NewSeries();
series.Name = seriesInfo.SeriesName;
series.Values = seriesInfo.ValuesY.ToArray();
series.XValues = seriesX;
SetSeriesColor(series, seriesInfo.Color);
series.MarkerStyle = Excel.XlMarkerStyle.xlMarkerStyleCircle;
series.MarkerSize = 5;
}
chart.HasLegend = true;
chart.Legend.Position = diagramInfo.LegendLayout switch
{
LegendLayoutEnum.Left => Word.XlLegendPosition.xlLegendPositionLeft,
LegendLayoutEnum.Top => Word.XlLegendPosition.xlLegendPositionTop,
LegendLayoutEnum.Right => Word.XlLegendPosition.xlLegendPositionRight,
LegendLayoutEnum.Bottom => Word.XlLegendPosition.xlLegendPositionBottom,
_ => Word.XlLegendPosition.xlLegendPositionBottom,
};
chart.ChartData.Workbook.Application.Quit();
}
private void SetSeriesColor(dynamic series, Color color)
{
series.Format.Line.ForeColor.RGB = ColorTranslator.ToOle(color);
series.Format.Fill.ForeColor.RGB = ColorTranslator.ToOle(color);
}
private void ValidateDiagramInfo(GraphicWordInfo diagramInfo)
{
if (string.IsNullOrEmpty(diagramInfo.Path) || string.IsNullOrEmpty(diagramInfo.DocumentTitle) ||
string.IsNullOrEmpty(diagramInfo.DiagramTitle) || diagramInfo.SeriesX == null ||
diagramInfo.SeriesX.Count == 0 || diagramInfo.SeriesParameters == null ||
diagramInfo.SeriesParameters.Count == 0)
{
throw new ArgumentException("Не все данные для диаграммы заполнены");
}
foreach (var series in diagramInfo.SeriesParameters)
{
if (string.IsNullOrEmpty(series.SeriesName))
{
throw new ArgumentException("Название серии не может быть пустым");
}
if (series.ValuesY == null || series.ValuesY.Count == 0)
{
throw new ArgumentException($"Список значений оси Y для серии '{series.SeriesName}' не заполнен");
}
if (diagramInfo.SeriesX.Count != series.ValuesY.Count)
{
throw new ArgumentException($"Количество данных оси X и значений оси Y для серии '{series.SeriesName}' не совпадает");
}
}
}
}
}

View File

@ -0,0 +1,36 @@
namespace WinFormsLibrary.NonVisualComponents
{
partial class WordTable
{
/// <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,187 @@
using Word = Microsoft.Office.Interop.Word;
using WinFormsLibrary.NonVisualComponents.Helpers;
using System.ComponentModel;
namespace WinFormsLibrary.NonVisualComponents
{
public partial class WordTable : Component
{
public WordTable()
{
InitializeComponent();
}
public WordTable(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public void CreateTable<T>(WordTableInfo<T> tableInfo)
{
ValidateInputData(tableInfo);
var wordApp = new Word.Application();
var document = wordApp.Documents.Add();
var range = document.Range();
var paragraph = range.Paragraphs.Add();
paragraph.Range.Text = tableInfo.Title;
paragraph.Range.Font.Name = "Times New Roman";
paragraph.Range.Font.Size = 20;
paragraph.Range.Font.Bold = 1;
paragraph.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
paragraph.Range.ParagraphFormat.SpaceAfter = 8;
paragraph.Range.InsertParagraphAfter();
var table = document.Tables.Add(paragraph.Range, tableInfo.Items.Count + 2, tableInfo.ColumnInfos.Count);
table.Borders.Enable = 1;
table.Range.Font.Name = "Times New Roman";
table.Range.Font.Size = 11;
for (int i = 0; i < tableInfo.ColumnInfos.Count; i++)
{
table.Columns[i + 1].Width = (float)(tableInfo.ColumnInfos[i].Width * 28);
}
AddTableHeaderRow(table, tableInfo.ColumnInfos, true);
AddTableHeaderRow(table, tableInfo.ColumnInfos, false);
MergeColumns(table, tableInfo.MergedColumns);
AddTableData(table, tableInfo.Items, tableInfo.ColumnInfos);
document.SaveAs2(tableInfo.Path);
wordApp.Quit();
}
private void AddTableHeaderRow(Word.Table table, List<ColumnInfo> columnInfos, bool isFirstRow)
{
for (int i = 0; i < columnInfos.Count; i++)
{
var header = isFirstRow ? columnInfos[i].FirstRowHeader : columnInfos[i].SecondRowHeader;
if (!string.IsNullOrEmpty(header))
{
var cell = table.Cell(isFirstRow ? 1 : 2, i + 1);
cell.Range.Text = header;
cell.Range.Bold = 1;
cell.Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
cell.VerticalAlignment = Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter;
cell.Range.ParagraphFormat.SpaceBefore = 4;
cell.Range.ParagraphFormat.SpaceAfter = 4;
}
}
}
private void MergeColumns(Word.Table table, List<(int start, int end)> mergedColumns)
{
for (int i = 1; i <= table.Columns.Count; i++)
{
bool isMergedHorizontally = mergedColumns.Any(m => m.start <= i - 1 && m.end >= i - 1);
if (!isMergedHorizontally)
{
table.Cell(1, i).Merge(table.Cell(2, i));
}
}
int xOffset = 0;
foreach (var (start, end) in mergedColumns)
{
var cellStart = table.Cell(1, start + 1 - xOffset);
var cellEnd = table.Cell(1, end + 1 - xOffset);
string textToKeep = cellStart.Range.Text.TrimEnd('\r', '\a');
cellStart.Merge(cellEnd);
cellStart.Range.Text = textToKeep;
xOffset += end - start;
}
}
private void AddTableData<T>(Word.Table table, List<T> items, List<ColumnInfo> columnInfos)
{
for (int rowIndex = 0; rowIndex < items.Count; rowIndex++)
{
var item = items[rowIndex];
for (int colIndex = 0; colIndex < columnInfos.Count; colIndex++)
{
var property = typeof(T).GetProperty(columnInfos[colIndex].PropertyName);
var value = property?.GetValue(item)?.ToString() ?? string.Empty;
table.Cell(rowIndex + 3, colIndex + 1).Range.Text = value;
table.Cell(rowIndex + 3, colIndex + 1).Range.Bold = 0;
table.Cell(rowIndex + 3, colIndex + 1).Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
table.Cell(rowIndex + 3, colIndex + 1).VerticalAlignment = Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter;
table.Cell(rowIndex + 3, colIndex + 1).Range.ParagraphFormat.SpaceBefore = 2;
table.Cell(rowIndex + 3, colIndex + 1).Range.ParagraphFormat.SpaceAfter = 2;
}
}
}
private void ValidateInputData<T>(WordTableInfo<T> wordTableInfo)
{
if (string.IsNullOrEmpty(wordTableInfo.Path) || (string.IsNullOrEmpty(wordTableInfo.Title)))
{
throw new ArgumentException("Не все данные заполнены");
}
CheckColumnInfo(wordTableInfo.ColumnInfos);
foreach (var column in wordTableInfo.ColumnInfos)
{
if (typeof(T).GetProperty(column.PropertyName) == null)
{
throw new ArgumentException($"Свойство '{column.PropertyName}' не найдено в классе {typeof(T).Name}.");
}
}
ValidateMergedColumns(wordTableInfo.MergedColumns, wordTableInfo.ColumnInfos.Count);
}
public void CheckColumnInfo(List<ColumnInfo> columns)
{
if ((columns == null) || (columns.Count == 0))
{
throw new ArgumentException("Нет информации о колонках");
}
foreach (var column in columns)
{
if (string.IsNullOrEmpty(column.FirstRowHeader) && string.IsNullOrEmpty(column.SecondRowHeader))
{
throw new ArgumentException("Заголовок не задан для одной из колонок в таблице");
}
if (column.Width <= 0)
{
throw new ArgumentException("Ширина колонки должна быть больше нуля.");
}
if (string.IsNullOrEmpty(column.PropertyName))
{
throw new ArgumentException("Свойство не задано для одной из колонок.");
}
}
}
private void ValidateMergedColumns(List<(int start, int end)> mergedColumns, int totalColumns)
{
if (mergedColumns == null || mergedColumns.Count == 0)
{
return;
}
foreach (var (start, end) in mergedColumns)
{
if (start < 0 || end >= totalColumns)
{
throw new ArgumentException("Индексы объединенных колонок вышли за пределы допустимых значений.");
}
var overlappingRanges = mergedColumns
.Where(m => m != (start, end))
.Any(m => m.start <= end && m.end >= start);
if (overlappingRanges)
{
throw new ArgumentException("Объединенные ячейки пересекаются.");
}
}
}
}
}

View File

@ -0,0 +1,36 @@
namespace WinFormsLibrary.NonVisualComponents
{
partial class WordText
{
/// <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,80 @@
using Microsoft.Office.Interop.Word;
using System.ComponentModel;
using WinFormsLibrary.NonVisualComponents.Helpers;
using Application = Microsoft.Office.Interop.Word.Application;
namespace WinFormsLibrary.NonVisualComponents
{
public partial class WordText : Component
{
private Application? _wordApp;
private Document? _document;
public WordText()
{
InitializeComponent();
}
public WordText(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public void CreateWordText(LongWordInfo textInfo)
{
if ((string.IsNullOrEmpty(textInfo.Path)) || (string.IsNullOrEmpty(textInfo.Title) || !CheckData(textInfo.Paragraphs)))
{
throw new ArgumentException("Не все данные заполнены");
}
_wordApp = new Application();
_document = _wordApp.Documents.Add();
try
{
AddText(textInfo);
_document.SaveAs2(textInfo.Path);
}
finally
{
_document.Close();
_wordApp.Quit();
}
}
private void AddText(LongWordInfo textInfo)
{
if (_document == null)
{
return;
}
AddParagraph(textInfo.Title, fontSize: 20, isBold: true);
foreach(var paragraph in textInfo.Paragraphs)
{
AddParagraph(paragraph, fontSize: 14, isBold: false);
}
}
private void AddParagraph(string text, int fontSize, bool isBold)
{
if (_document== null)
{
return;
}
var paragraph = _document.Content.Paragraphs.Add();
var range = paragraph.Range;
range.Text = text;
range.Font.Size = fontSize;
range.Font.Name = "Times New Roman";
range.Font.Bold = isBold ? 1 : 0;
paragraph.Alignment = WdParagraphAlignment.wdAlignParagraphJustify;
range.InsertParagraphAfter();
}
public bool CheckData(string[] data)
{
return data != null && data.Any() && data.All(dt => !String.IsNullOrEmpty(dt));
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinFormsLibrary.Object
{
public class Example
{
public int Id { get; set; }
public string Status { get; set; } = string.Empty;
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public int Age { get; set; }
public string Children { get; set; } = string.Empty;
public string Car { get; set; } = string.Empty;
public string Department { get; set; } = string.Empty;
public string Position { get; set; } = string.Empty;
public double Bonus { get; set; }
}
}

View File

@ -29,43 +29,31 @@
private void InitializeComponent()
{
this.comboBox = new System.Windows.Forms.ComboBox();
this.labelDropDownList = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// comboBox
//
this.comboBox.FormattingEnabled = true;
this.comboBox.Location = new System.Drawing.Point(3, 60);
this.comboBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.comboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox.Location = new System.Drawing.Point(0, 0);
this.comboBox.Name = "comboBox";
this.comboBox.Size = new System.Drawing.Size(182, 33);
this.comboBox.Size = new System.Drawing.Size(199, 33);
this.comboBox.TabIndex = 0;
this.comboBox.SelectedIndexChanged += new System.EventHandler(this.comboBox_SelectedIndexChanged);
//
// labelDropDownList
//
this.labelDropDownList.AutoSize = true;
this.labelDropDownList.Location = new System.Drawing.Point(3, 12);
this.labelDropDownList.Name = "labelDropDownList";
this.labelDropDownList.Size = new System.Drawing.Size(184, 25);
this.labelDropDownList.TabIndex = 1;
this.labelDropDownList.Text = "Выпадающий список";
//
// DropDownList
//
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.labelDropDownList);
this.Controls.Add(this.comboBox);
this.Name = "DropDownList";
this.Size = new System.Drawing.Size(199, 105);
this.Size = new System.Drawing.Size(199, 34);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private ComboBox comboBox;
private Label labelDropDownList;
}
}

View File

@ -31,35 +31,25 @@
this.components = new System.ComponentModel.Container();
this.textBoxEmail = new System.Windows.Forms.TextBox();
this.toolTipEmail = new System.Windows.Forms.ToolTip(this.components);
this.labelEmail = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// textBoxEmail
//
this.textBoxEmail.Location = new System.Drawing.Point(0, 55);
this.textBoxEmail.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBoxEmail.Location = new System.Drawing.Point(0, 0);
this.textBoxEmail.Name = "textBoxEmail";
this.textBoxEmail.Size = new System.Drawing.Size(181, 31);
this.textBoxEmail.Size = new System.Drawing.Size(146, 31);
this.textBoxEmail.TabIndex = 0;
this.textBoxEmail.TextChanged += new System.EventHandler(this.textBoxEmail_TextChanged);
this.textBoxEmail.MouseEnter += new System.EventHandler(this.textBoxEmail_MouseEnter);
//
// labelEmail
//
this.labelEmail.AutoSize = true;
this.labelEmail.Location = new System.Drawing.Point(3, 6);
this.labelEmail.Name = "labelEmail";
this.labelEmail.Size = new System.Drawing.Size(129, 25);
this.labelEmail.TabIndex = 1;
this.labelEmail.Text = "Введите почту";
//
// EmailTextBox
//
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.labelEmail);
this.Controls.Add(this.textBoxEmail);
this.Name = "EmailTextBox";
this.Size = new System.Drawing.Size(209, 118);
this.Size = new System.Drawing.Size(146, 33);
this.ResumeLayout(false);
this.PerformLayout();
@ -69,6 +59,5 @@
private TextBox textBoxEmail;
private ToolTip toolTipEmail;
private Label labelEmail;
}
}

View File

@ -0,0 +1,158 @@
using System.Reflection;
namespace WinFormsLibrary
{
public partial class ListBoxValues : UserControl
{
private string _layout;
private char? _endSymbol;
private char? _startSymbol;
public ListBoxValues()
{
InitializeComponent();
}
public void SetLayout(string layout, char? startSymbol, char? endSymbol)
{
if (layout == null)
{
return;
}
_layout = layout;
_endSymbol = endSymbol;
_startSymbol = startSymbol;
}
public int SelectedIndex
{
get
{
if (listBoxObjects.SelectedIndex == -1)
{
return -1;
}
return listBoxObjects.SelectedIndex;
}
set
{
if (listBoxObjects.SelectedItems.Count != 0)
{
listBoxObjects.SelectedIndex = value;
}
}
}
public T GetObjectFromStr<T>() where T : class, new()
{
if (listBoxObjects.SelectedIndex == -1 || string.IsNullOrEmpty(_layout) || !_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 = listBoxObjects.SelectedItem?.ToString() ?? "";
var words = System.Text.RegularExpressions.Regex.Split(_layout, $@"\{_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(_layout.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 = _layout.Substring(_layout.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;
}
public void AddItems<T>(List<T> items)
where T : class
{
if (string.IsNullOrEmpty(_layout) || !_startSymbol.HasValue || !_endSymbol.HasValue)
throw new ArgumentException("Не хватает данных");
listBoxObjects.Items.Clear();
var type = typeof(T);
var fields = type.GetFields();
var properties = type.GetProperties();
var members = fields.Cast<MemberInfo>().Concat(properties.Cast<MemberInfo>()).ToArray();
foreach (T item in items)
{
string result = _layout;
foreach (var member in members)
{
string search = _startSymbol.Value + member.Name +_endSymbol.Value;
object? value = null;
if (member is FieldInfo field)
{
value = field.GetValue(item);
}
if (member is PropertyInfo property)
{
if (property.CanRead)
{
value = property.GetValue(item);
}
}
result = result.Replace(search, value?.ToString() ?? "");
}
listBoxObjects.Items.Add(result);
}
}
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;
}
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);
}
}
}
}

View File

@ -0,0 +1,60 @@
<root>
<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,41 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<COMReference Include="Microsoft.Office.Core">
<WrapperTool>tlbimp</WrapperTool>
<VersionMinor>8</VersionMinor>
<VersionMajor>2</VersionMajor>
<Guid>2df8d04c-5bfa-101b-bde5-00aa0044de52</Guid>
<Lcid>0</Lcid>
<Isolated>false</Isolated>
<EmbedInteropTypes>true</EmbedInteropTypes>
</COMReference>
<COMReference Include="Microsoft.Office.Interop.Excel">
<WrapperTool>tlbimp</WrapperTool>
<VersionMinor>9</VersionMinor>
<VersionMajor>1</VersionMajor>
<Guid>00020813-0000-0000-c000-000000000046</Guid>
<Lcid>0</Lcid>
<Isolated>false</Isolated>
<EmbedInteropTypes>true</EmbedInteropTypes>
</COMReference>
<COMReference Include="Microsoft.Office.Interop.Word">
<WrapperTool>tlbimp</WrapperTool>
<VersionMinor>7</VersionMinor>
<VersionMajor>8</VersionMajor>
<Guid>00020905-0000-0000-c000-000000000046</Guid>
<Lcid>0</Lcid>
<Isolated>false</Isolated>
<EmbedInteropTypes>true</EmbedInteropTypes>
</COMReference>
</ItemGroup>
</Project>

188
WindowsFormAppPlugin/FormMain.Designer.cs generated Normal file
View File

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

View File

@ -0,0 +1,235 @@
using PluginsConventionLibrary;
using System.Reflection;
namespace WindowsFormAppPlugin
{
public partial class FormMain : Form
{
private readonly Dictionary<string, IPluginsConvention> _plugins;
private string _selectedPlugin;
public FormMain()
{
InitializeComponent();
_plugins = LoadPlugins();
_selectedPlugin = string.Empty;
}
private Dictionary<string, IPluginsConvention> LoadPlugins()
{
var plugins = new Dictionary<string, IPluginsConvention>();
string pluginsDir = Path.Combine(Directory.GetParent(Directory.GetCurrentDirectory())!.Parent!.Parent!.FullName, "Plugins");
if (!Directory.Exists(pluginsDir))
{
MessageBox.Show($"Каталог {pluginsDir} не найден.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return plugins;
}
foreach (string dllFile in Directory.EnumerateFiles(pluginsDir, "*.dll", SearchOption.AllDirectories))
{
try
{
Assembly assembly = Assembly.LoadFrom(dllFile);
Type[] types = assembly.GetTypes();
foreach (var type in types)
{
if (typeof(IPluginsConvention).IsAssignableFrom(type) && !type.IsInterface && !type.IsAbstract)
{
var plugin = (IPluginsConvention)Activator.CreateInstance(type)!;
plugins.Add(plugin.PluginName, plugin);
CreateToolStripMenuItem(plugin.PluginName);
}
}
}
catch (Exception ex)
{
MessageBox.Show($"Ошибка при загрузке сборки {dllFile}: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
return plugins;
}
private void CreateToolStripMenuItem(string pluginName)
{
var menuItem = new ToolStripMenuItem(pluginName);
menuItem.Click += (object? sender, EventArgs e) =>
{
_selectedPlugin = pluginName;
IPluginsConvention plugin = _plugins![pluginName];
UserControl userControl = plugin?.GetControl ?? throw new Exception("Проблема с загрузкой элемента для вывода данных");
panelControl.Controls.Clear();
plugin.ReloadData();
userControl.Dock = DockStyle.Fill;
panelControl.Controls.Add(userControl);
};
ControlsStripMenuItem.DropDownItems.Add(menuItem);
}
private void FormMain_KeyDown(object sender, KeyEventArgs e)
{
if (string.IsNullOrEmpty(_selectedPlugin) ||
!_plugins.ContainsKey(_selectedPlugin))
{
return;
}
if (!e.Control)
{
return;
}
switch (e.KeyCode)
{
case Keys.I:
ShowThesaurus();
break;
case Keys.A:
AddNewElement();
break;
case Keys.U:
UpdateElement();
break;
case Keys.D:
DeleteElement();
break;
case Keys.S:
CreateSimpleDoc();
break;
case Keys.T:
CreateTableDoc();
break;
case Keys.C:
CreateChartDoc();
break;
}
}
private void ShowThesaurus()
{
_plugins[_selectedPlugin].GetThesaurus()?.Show();
}
private void AddNewElement()
{
var form = _plugins[_selectedPlugin].GetForm(null);
if (form != null && form.ShowDialog() == DialogResult.OK)
{
_plugins[_selectedPlugin].ReloadData();
}
}
private void UpdateElement()
{
var element = _plugins[_selectedPlugin].GetElement;
if (element == null)
{
MessageBox.Show("Нет выбранного элемента", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
var form = _plugins[_selectedPlugin].GetForm(element);
if (form != null && form.ShowDialog() == DialogResult.OK)
{
_plugins[_selectedPlugin].ReloadData();
}
}
private void DeleteElement()
{
if (MessageBox.Show("Удалить выбранный элемент", "Удаление",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
{
return;
}
var element = _plugins[_selectedPlugin].GetElement;
if (element == null)
{
MessageBox.Show("Нет выбранного элемента", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (_plugins[_selectedPlugin].DeleteElement(element))
{
_plugins[_selectedPlugin].ReloadData();
}
}
private void CreateSimpleDoc()
{
using var dialog = new SaveFileDialog
{
Filter = "docx|*.docx"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
if (_plugins[_selectedPlugin].CreateSimpleDocument(new PluginsConventionSaveDocument() { FileName = dialog.FileName}))
{
MessageBox.Show("Документ сохранен", "Создание документа", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Ошибка при создании документа", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (Exception ex)
{
MessageBox.Show("Произошла ошибка: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void CreateTableDoc()
{
using var dialog = new SaveFileDialog
{
Filter = "PDF Files|*.pdf"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
if (_plugins[_selectedPlugin].CreateTableDocument(new PluginsConventionSaveDocument() { FileName = dialog.FileName }))
{
MessageBox.Show("Документ сохранен", "Создание документа", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Ошибка при создании документа",
"Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (Exception ex)
{
MessageBox.Show("Произошла ошибка: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void CreateChartDoc()
{
using var dialog = new SaveFileDialog
{
Filter = "Excel Files|*.xlsx"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
if (_plugins[_selectedPlugin].CreateChartDocument(new PluginsConventionSaveDocument() { FileName = dialog.FileName }))
{
MessageBox.Show("Документ сохранен", "Создание документа", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Ошибка при создании документа", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (Exception ex)
{
MessageBox.Show("Произошла ошибка: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void ThesaurusToolStripMenuItem_Click(object sender, EventArgs e) => ShowThesaurus();
private void AddElementToolStripMenuItem_Click(object sender, EventArgs e) => AddNewElement();
private void UpdElementToolStripMenuItem_Click(object sender, EventArgs e) => UpdateElement();
private void DelElementToolStripMenuItem_Click(object sender, EventArgs e) => DeleteElement();
private void SimpleDocToolStripMenuItem_Click(object sender, EventArgs e) => CreateSimpleDoc();
private void TableDocToolStripMenuItem_Click(object sender, EventArgs e) => CreateTableDoc();
private void ChartDocToolStripMenuItem_Click(object sender, EventArgs e) => CreateChartDoc();
}
}

View File

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

View File

@ -0,0 +1,17 @@
namespace WindowsFormAppPlugin
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new FormMain());
}
}
}

View File

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net7.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PluginConventionLibrary\PluginConventionLibrary.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="FormMain.cs">
<SubType>Form</SubType>
</Compile>
</ItemGroup>
</Project>