4 Commits
Lab1 ... Lab4

Author SHA1 Message Date
Владимир Данилов
1a3a93e44a Лаб4 2024-12-12 22:05:42 +04:00
Владимир Данилов
df6647c3b4 -_- 2024-12-12 19:20:18 +04:00
Владимир Данилов
8b375b106e ... 2024-12-11 14:17:36 +04:00
Владимир Данилов
d9ce6d6a8e Добавление/удаление/отображение 2024-11-28 01:31:31 +04:00
111 changed files with 3089 additions and 0 deletions

View File

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

View File

@@ -0,0 +1,93 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicContracts;
using Contracts.SearchModels;
using Contracts.StorageContracts;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLogic.BusinessLogics
{
public class AccountLogic : IAccountLogic
{
private readonly IAccountStorage _accountStorage;
public AccountLogic(IAccountStorage accountStorage)
{
_accountStorage = accountStorage;
}
public bool Create(AccountBindingModel model)
{
CheckModel(model);
if (_accountStorage.Insert(model) == null)
{
return false;
}
return true;
}
public bool Delete(AccountBindingModel model)
{
CheckModel(model, false);
if (_accountStorage.Delete(model) == null)
{
return false;
}
return true;
}
public AccountViewModel? ReadElement(AccountSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
var element = _accountStorage.GetElement(model);
if (element == null)
{
return null;
}
return element;
}
public List<AccountViewModel>? ReadList(AccountSearchModel? model)
{
var list = model == null ? _accountStorage.GetFullList() : _accountStorage.GetFilteredList(model);
if (list == null)
{
return null;
}
return list;
}
public bool Update(AccountBindingModel model)
{
CheckModel(model);
if (_accountStorage.Update(model) == null)
{
return false;
}
return true;
}
private void CheckModel(AccountBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.Login))
{
throw new ArgumentNullException("Нет логина", nameof(model.Login));
}
}
}
}

View File

@@ -0,0 +1,93 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicContracts;
using Contracts.SearchModels;
using Contracts.StorageContracts;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLogic.BusinessLogics
{
public class CityLogic : ICityLogic
{
private readonly ICityStorage _cityStorage;
public CityLogic(ICityStorage cityStorage)
{
_cityStorage = cityStorage;
}
public bool Create(CityBindingModel model)
{
CheckModel(model);
if (_cityStorage.Insert(model) == null)
{
return false;
}
return true;
}
public bool Delete(CityBindingModel model)
{
CheckModel(model, false);
if (_cityStorage.Delete(model) == null)
{
return false;
}
return true;
}
public CityViewModel? ReadElement(CitySearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
var element = _cityStorage.GetElement(model);
if (element == null)
{
return null;
}
return element;
}
public List<CityViewModel>? ReadList(CitySearchModel? model)
{
var list = model == null ? _cityStorage.GetFullList() : _cityStorage.GetFilteredList(model);
if (list == null)
{
return null;
}
return list;
}
public bool Update(CityBindingModel model)
{
CheckModel(model);
if (_cityStorage.Update(model) == null)
{
return false;
}
return true;
}
private void CheckModel(CityBindingModel 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));
}
}
}
}

View File

@@ -0,0 +1,22 @@
using DataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.BindingModels
{
public class AccountBindingModel : IAccountModel
{
public int Id { get; set; }
public string Login { get; set; } = string.Empty;
public List<DateTime> AuthorizationAttemptsHistory { get; set; } = new List<DateTime>();
public int ResidenceCityId { get; set; }
public DateTime AccountCreationDate { get; set; }
}
}

View File

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

View File

@@ -0,0 +1,20 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.BusinessLogicContracts
{
public interface IAccountLogic
{
List<AccountViewModel>? ReadList(AccountSearchModel? model);
AccountViewModel? ReadElement(AccountSearchModel model);
bool Create(AccountBindingModel model);
bool Update(AccountBindingModel model);
bool Delete(AccountBindingModel model);
}
}

View File

@@ -0,0 +1,20 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.BusinessLogicContracts
{
public interface ICityLogic
{
List<CityViewModel>? ReadList(CitySearchModel? model);
CityViewModel? ReadElement(CitySearchModel model);
bool Create(CityBindingModel model);
bool Update(CityBindingModel model);
bool Delete(CityBindingModel model);
}
}

View File

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

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.SearchModels
{
public class AccountSearchModel
{
public int? Id { get; set; }
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.SearchModels
{
public class CitySearchModel
{
public int? Id { get; set; }
}
}

View File

@@ -0,0 +1,21 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.StorageContracts
{
public interface IAccountStorage
{
List<AccountViewModel> GetFullList();
List<AccountViewModel> GetFilteredList(AccountSearchModel model);
AccountViewModel? GetElement(AccountSearchModel model);
AccountViewModel? Insert(AccountBindingModel model);
AccountViewModel? Update(AccountBindingModel model);
AccountViewModel? Delete(AccountBindingModel model);
}
}

View File

@@ -0,0 +1,21 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.StorageContracts
{
public interface ICityStorage
{
List<CityViewModel> GetFullList();
List<CityViewModel> GetFilteredList(CitySearchModel model);
CityViewModel? GetElement(CitySearchModel model);
CityViewModel? Insert(CityBindingModel model);
CityViewModel? Update(CityBindingModel model);
CityViewModel? Delete(CityBindingModel model);
}
}

View File

@@ -0,0 +1,28 @@
using DataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.ViewModels
{
public class AccountViewModel : IAccountModel
{
[DisplayName("Логин")]
public string Login { get; set; } = string.Empty;
[DisplayName("История авторизаций")]
public List<DateTime> AuthorizationAttemptsHistory { get; set; }
[DisplayName("Город проживания")]
public string ResidenceCityName { get; set; }
public int ResidenceCityId { get; set; }
[DisplayName("Дата создания аккаунта")]
public DateTime AccountCreationDate { get; set; }
public int Id { get; set; }
}
}

View File

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

View File

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

7
Lab3/DataModels/IId.cs Normal file
View File

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

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataModels.Models
{
public interface IAccountModel: IId
{
// Логин
string Login { get; }
// Даты последних попыток авторизации
List<DateTime> AuthorizationAttemptsHistory { get; }
// Город проживания
int ResidenceCityId { get; }
// Дата создания аккаунта (последние 10 лет)
DateTime AccountCreationDate { get; }
}
}

View File

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

View File

@@ -0,0 +1,15 @@
using DatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
namespace DatabaseImplement
{
public class AccountsDatabase : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseNpgsql("Host=localhost;Port=5432;Database=COPAccountsBD;Username=postgres;Password=postgres");
public virtual DbSet<Accounts> Accounts { set; get; }
public virtual DbSet<Cities> Cities { set; get; }
}
}

View File

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

View File

@@ -0,0 +1,96 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.StorageContracts;
using Contracts.ViewModels;
using DatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement.Implements
{
public class AccountStorage : IAccountStorage
{
public AccountViewModel? Delete(AccountBindingModel model)
{
using var context = new AccountsDatabase();
var element = context.Accounts
.Include(x => x.ResidenceCity)
.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Accounts.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
public AccountViewModel? GetElement(AccountSearchModel model)
{
if (!model.Id.HasValue)
{
return null;
}
using var context = new AccountsDatabase();
return context.Accounts
.Include(x => x.ResidenceCity)
.FirstOrDefault(x => x.Id == model.Id)
?.GetViewModel;
}
public List<AccountViewModel> GetFilteredList(AccountSearchModel model)
{
if (!model.Id.HasValue)
{
return new();
}
using var context = new AccountsDatabase();
return context.Accounts
.Include(x => x.ResidenceCity)
.Where(x => x.Id == model.Id)
.Select(x => x.GetViewModel)
.ToList();
}
public List<AccountViewModel> GetFullList()
{
using var context = new AccountsDatabase();
return context.Accounts
.Include(x => x.ResidenceCity)
.Select(x => x.GetViewModel)
.ToList();
}
public AccountViewModel? Insert(AccountBindingModel model)
{
using var context = new AccountsDatabase();
var newAccount = Accounts.Create(context, model);
if (newAccount == null)
{
return null;
}
context.Accounts.Add(newAccount);
context.SaveChanges();
return newAccount.GetViewModel;
}
public AccountViewModel? Update(AccountBindingModel model)
{
using var context = new AccountsDatabase();
var Account = context.Accounts.FirstOrDefault(x => x.Id == model.Id);
if (Account == null)
{
return null;
}
Account.Update(model, context);
context.SaveChanges();
return Account.GetViewModel;
}
}
}

View File

@@ -0,0 +1,88 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.StorageContracts;
using Contracts.ViewModels;
using DatabaseImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement.Implements
{
public class CityStorage : ICityStorage
{
public CityViewModel? Delete(CityBindingModel model)
{
using var context = new AccountsDatabase();
var element = context.Cities.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Cities.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
public CityViewModel? GetElement(CitySearchModel model)
{
if (!model.Id.HasValue)
{
return null;
}
using var context = new AccountsDatabase();
return context.Cities
.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)
?.GetViewModel;
}
public List<CityViewModel> GetFilteredList(CitySearchModel model)
{
if (!model.Id.HasValue)
{
return new();
}
using var context = new AccountsDatabase();
return context.Cities
.Where(x => x.Id == model.Id)
.Select(x => x.GetViewModel)
.ToList();
}
public List<CityViewModel> GetFullList()
{
using var context = new AccountsDatabase();
return context.Cities
.Select(x => x.GetViewModel)
.ToList();
}
public CityViewModel? Insert(CityBindingModel model)
{
var newcity = Cities.Create(model);
if (newcity == null)
{
return null;
}
using var context = new AccountsDatabase();
context.Cities.Add(newcity);
context.SaveChanges();
return newcity.GetViewModel;
}
public CityViewModel? Update(CityBindingModel model)
{
using var context = new AccountsDatabase();
var component = context.Cities.FirstOrDefault(x => x.Id == model.Id);
if (component == null)
{
return null;
}
component.Update(model);
context.SaveChanges();
return component.GetViewModel;
}
}
}

View File

@@ -0,0 +1,88 @@
// <auto-generated />
using System;
using System.Collections.Generic;
using DatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace DatabaseImplement.Migrations
{
[DbContext(typeof(AccountsDatabase))]
[Migration("20241127202901_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("DatabaseImplement.Models.Accounts", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTime>("AccountCreationDate")
.HasColumnType("timestamp with time zone");
b.PrimitiveCollection<List<DateTime>>("AuthorizationAttemptsHistory")
.IsRequired()
.HasColumnType("timestamp with time zone[]");
b.Property<string>("Login")
.IsRequired()
.HasColumnType("text");
b.Property<int>("ResidenceCityId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("ResidenceCityId");
b.ToTable("Accounts");
});
modelBuilder.Entity("DatabaseImplement.Models.Cities", 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("Cities");
});
modelBuilder.Entity("DatabaseImplement.Models.Accounts", b =>
{
b.HasOne("DatabaseImplement.Models.Cities", "ResidenceCity")
.WithMany()
.HasForeignKey("ResidenceCityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ResidenceCity");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace DatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Cities",
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_Cities", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Accounts",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Login = table.Column<string>(type: "text", nullable: false),
AuthorizationAttemptsHistory = table.Column<List<DateTime>>(type: "timestamp with time zone[]", nullable: false),
ResidenceCityId = table.Column<int>(type: "integer", nullable: false),
AccountCreationDate = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Accounts", x => x.Id);
table.ForeignKey(
name: "FK_Accounts_Cities_ResidenceCityId",
column: x => x.ResidenceCityId,
principalTable: "Cities",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Accounts_ResidenceCityId",
table: "Accounts",
column: "ResidenceCityId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Accounts");
migrationBuilder.DropTable(
name: "Cities");
}
}
}

View File

@@ -0,0 +1,85 @@
// <auto-generated />
using System;
using System.Collections.Generic;
using DatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace DatabaseImplement.Migrations
{
[DbContext(typeof(AccountsDatabase))]
partial class AccountsDatabaseModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("DatabaseImplement.Models.Accounts", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTime>("AccountCreationDate")
.HasColumnType("timestamp with time zone");
b.PrimitiveCollection<List<DateTime>>("AuthorizationAttemptsHistory")
.IsRequired()
.HasColumnType("timestamp with time zone[]");
b.Property<string>("Login")
.IsRequired()
.HasColumnType("text");
b.Property<int>("ResidenceCityId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("ResidenceCityId");
b.ToTable("Accounts");
});
modelBuilder.Entity("DatabaseImplement.Models.Cities", 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("Cities");
});
modelBuilder.Entity("DatabaseImplement.Models.Accounts", b =>
{
b.HasOne("DatabaseImplement.Models.Cities", "ResidenceCity")
.WithMany()
.HasForeignKey("ResidenceCityId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ResidenceCity");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,67 @@
using Contracts.BindingModels;
using Contracts.ViewModels;
using DataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement.Models
{
public class Accounts : IAccountModel
{
[Required]
public string Login { get; set; } = string.Empty;
public List<DateTime> AuthorizationAttemptsHistory { get; set; } = new List<DateTime>();
public int ResidenceCityId { get; set; }
public virtual Cities ResidenceCity { get; set; } = new();
public DateTime AccountCreationDate { get; set; }
public int Id { get; private set; }
public static Accounts? Create(AccountsDatabase context, AccountBindingModel? model)
{
if (model == null)
{
return null;
}
return new Accounts()
{
Id = model.Id,
Login = model.Login,
ResidenceCityId = model.ResidenceCityId,
ResidenceCity = context.Cities.First(x => x.Id == model.ResidenceCityId),
AuthorizationAttemptsHistory = model.AuthorizationAttemptsHistory.Select(date => date.ToUniversalTime()).ToList(),
AccountCreationDate = model.AccountCreationDate.ToUniversalTime()
};
}
public void Update(AccountBindingModel? model, AccountsDatabase context)
{
if (model == null)
{
return;
}
Login = model.Login;
ResidenceCityId = model.ResidenceCityId;
ResidenceCity = context.Cities.First(x => x.Id == model.ResidenceCityId);
AuthorizationAttemptsHistory = model.AuthorizationAttemptsHistory.Select(date => date.ToUniversalTime()).ToList();
AccountCreationDate = model.AccountCreationDate.ToUniversalTime();
}
public AccountViewModel GetViewModel => new()
{
Id = Id,
Login = Login,
ResidenceCityId = ResidenceCity.Id,
ResidenceCityName = ResidenceCity.Name,
AuthorizationAttemptsHistory = AuthorizationAttemptsHistory,
AccountCreationDate = AccountCreationDate,
};
}
}

View File

@@ -0,0 +1,54 @@
using Contracts.BindingModels;
using Contracts.ViewModels;
using DataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement.Models
{
public class Cities : ICityModel
{
[Required]
public string Name { get; private set; } = string.Empty;
public int Id { get; private set; }
public static Cities? Create(CityBindingModel? model)
{
if (model == null)
{
return null;
}
return new Cities()
{
Id = model.Id,
Name = model.Name,
};
}
public static Cities? Create(CityViewModel? model)
{
return new Cities()
{
Id = model.Id,
Name = model.Name,
};
}
public void Update(CityBindingModel? model)
{
if (model == null)
{
return;
}
Name = model.Name;
}
public CityViewModel GetViewModel => new()
{
Id = Id,
Name = Name,
};
}
}

55
Lab3/Lab3.sln Normal file
View File

@@ -0,0 +1,55 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34330.188
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataModels", "DataModels\DataModels.csproj", "{1A0D3060-AA07-4FE1-B35F-C50BDBD7DC11}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinForms", "WinForms\WinForms.csproj", "{41510F7C-2870-4639-A9C0-21B45A670051}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BusinessLogic", "BusinessLogic\BusinessLogic.csproj", "{2F353788-82CB-41FB-9F30-0677595B324F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contracts", "Contracts\Contracts.csproj", "{4E33A514-74DF-4249-BC9A-577A9DE2428A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DatabaseImplement", "DatabaseImplement\DatabaseImplement.csproj", "{3E515C5F-ACF7-4980-B13F-4A2BC6E08D93}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginsConventionLibrary", "PluginsConventionLibrarys\PluginsConventionLibrary.csproj", "{802363FC-E4F5-4EEF-A41A-FF1195877C36}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1A0D3060-AA07-4FE1-B35F-C50BDBD7DC11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A0D3060-AA07-4FE1-B35F-C50BDBD7DC11}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A0D3060-AA07-4FE1-B35F-C50BDBD7DC11}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A0D3060-AA07-4FE1-B35F-C50BDBD7DC11}.Release|Any CPU.Build.0 = Release|Any CPU
{41510F7C-2870-4639-A9C0-21B45A670051}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{41510F7C-2870-4639-A9C0-21B45A670051}.Debug|Any CPU.Build.0 = Debug|Any CPU
{41510F7C-2870-4639-A9C0-21B45A670051}.Release|Any CPU.ActiveCfg = Release|Any CPU
{41510F7C-2870-4639-A9C0-21B45A670051}.Release|Any CPU.Build.0 = Release|Any CPU
{2F353788-82CB-41FB-9F30-0677595B324F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F353788-82CB-41FB-9F30-0677595B324F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F353788-82CB-41FB-9F30-0677595B324F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F353788-82CB-41FB-9F30-0677595B324F}.Release|Any CPU.Build.0 = Release|Any CPU
{4E33A514-74DF-4249-BC9A-577A9DE2428A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E33A514-74DF-4249-BC9A-577A9DE2428A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E33A514-74DF-4249-BC9A-577A9DE2428A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E33A514-74DF-4249-BC9A-577A9DE2428A}.Release|Any CPU.Build.0 = Release|Any CPU
{3E515C5F-ACF7-4980-B13F-4A2BC6E08D93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3E515C5F-ACF7-4980-B13F-4A2BC6E08D93}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E515C5F-ACF7-4980-B13F-4A2BC6E08D93}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E515C5F-ACF7-4980-B13F-4A2BC6E08D93}.Release|Any CPU.Build.0 = Release|Any CPU
{802363FC-E4F5-4EEF-A41A-FF1195877C36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{802363FC-E4F5-4EEF-A41A-FF1195877C36}.Debug|Any CPU.Build.0 = Debug|Any CPU
{802363FC-E4F5-4EEF-A41A-FF1195877C36}.Release|Any CPU.ActiveCfg = Release|Any CPU
{802363FC-E4F5-4EEF-A41A-FF1195877C36}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {76DCE003-B6A2-426C-87F2-C9C12FCB3691}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
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,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<UseWindowsForms>true</UseWindowsForms>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

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

View File

@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
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,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

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

229
Lab3/WinForms/FormAccount.Designer.cs generated Normal file
View File

@@ -0,0 +1,229 @@
using System.Windows.Forms;
namespace WinForms
{
partial class FormAccount
{
/// <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()
{
labelLogin = new Label();
textBoxLogin = new TextBox();
labelcity = new Label();
buttonCancel = new Button();
buttonSave = new Button();
openFileDialog = new OpenFileDialog();
label1 = new Label();
label2 = new Label();
listBoxDates = new ListBox();
dateTimePickerControl1 = new PutincevLibrary.DateTimePickerControl();
dateTimePicker1 = new DateTimePicker();
buttonAddDate = new Button();
checkedListBoxControl1 = new PutincevLibrary.CheckedListBoxControl();
buttonUpdateDate = new Button();
buttonDeleteDate = new Button();
SuspendLayout();
//
// labelLogin
//
labelLogin.AutoSize = true;
labelLogin.Location = new Point(10, 7);
labelLogin.Name = "labelLogin";
labelLogin.Size = new Size(41, 15);
labelLogin.TabIndex = 0;
labelLogin.Text = "Логин";
//
// textBoxLogin
//
textBoxLogin.Location = new Point(10, 24);
textBoxLogin.Margin = new Padding(3, 2, 3, 2);
textBoxLogin.Name = "textBoxLogin";
textBoxLogin.Size = new Size(241, 23);
textBoxLogin.TabIndex = 1;
//
// labelcity
//
labelcity.AutoSize = true;
labelcity.Location = new Point(10, 62);
labelcity.Name = "labelcity";
labelcity.Size = new Size(112, 15);
labelcity.TabIndex = 4;
labelcity.Text = "Город проживания";
//
// buttonCancel
//
buttonCancel.Location = new Point(162, 416);
buttonCancel.Margin = new Padding(3, 2, 3, 2);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(83, 21);
buttonCancel.TabIndex = 7;
buttonCancel.Text = "Отменить";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(13, 416);
buttonSave.Margin = new Padding(3, 2, 3, 2);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(94, 21);
buttonSave.TabIndex = 8;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// openFileDialog
//
openFileDialog.FileName = "openFileDialog";
openFileDialog.Multiselect = true;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(13, 375);
label1.Name = "label1";
label1.Size = new Size(136, 15);
label1.TabIndex = 10;
label1.Text = "Дата создания аккаунта";
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(13, 192);
label2.Name = "label2";
label2.Size = new Size(151, 15);
label2.TabIndex = 12;
label2.Text = "Даты ранних авторизаций";
//
// listBoxDates
//
listBoxDates.FormattingEnabled = true;
listBoxDates.ItemHeight = 15;
listBoxDates.Location = new Point(10, 210);
listBoxDates.Name = "listBoxDates";
listBoxDates.SelectionMode = SelectionMode.MultiExtended;
listBoxDates.Size = new Size(231, 94);
listBoxDates.TabIndex = 19;
//
// dateTimePickerControl1
//
dateTimePickerControl1.Location = new Point(13, 392);
dateTimePickerControl1.Margin = new Padding(3, 2, 3, 2);
dateTimePickerControl1.MaxValue = null;
dateTimePickerControl1.MinValue = null;
dateTimePickerControl1.Name = "dateTimePickerControl1";
dateTimePickerControl1.Size = new Size(228, 20);
dateTimePickerControl1.TabIndex = 20;
//
// dateTimePicker1
//
dateTimePicker1.Location = new Point(13, 310);
dateTimePicker1.Name = "dateTimePicker1";
dateTimePicker1.Size = new Size(228, 23);
dateTimePicker1.TabIndex = 22;
//
// buttonAddDate
//
buttonAddDate.Location = new Point(13, 339);
buttonAddDate.Name = "buttonAddDate";
buttonAddDate.Size = new Size(75, 23);
buttonAddDate.TabIndex = 23;
buttonAddDate.Text = "Добавить";
buttonAddDate.UseVisualStyleBackColor = true;
buttonAddDate.Click += buttonAddDate_Click;
//
// checkedListBoxControl1
//
checkedListBoxControl1.Location = new Point(10, 79);
checkedListBoxControl1.Margin = new Padding(3, 2, 3, 2);
checkedListBoxControl1.Name = "checkedListBoxControl1";
checkedListBoxControl1.Size = new Size(231, 102);
checkedListBoxControl1.TabIndex = 24;
//
// buttonUpdateDate
//
buttonUpdateDate.Location = new Point(89, 339);
buttonUpdateDate.Name = "buttonUpdateDate";
buttonUpdateDate.Size = new Size(75, 23);
buttonUpdateDate.TabIndex = 25;
buttonUpdateDate.Text = "Обновить";
buttonUpdateDate.UseVisualStyleBackColor = true;
buttonUpdateDate.Click += buttonUpdateDate_Click;
//
// buttonDeleteDate
//
buttonDeleteDate.Location = new Point(166, 339);
buttonDeleteDate.Name = "buttonDeleteDate";
buttonDeleteDate.Size = new Size(75, 23);
buttonDeleteDate.TabIndex = 26;
buttonDeleteDate.Text = "Удалить";
buttonDeleteDate.UseVisualStyleBackColor = true;
buttonDeleteDate.Click += buttonDeleteDate_Click;
//
// FormAccount
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(256, 449);
Controls.Add(buttonDeleteDate);
Controls.Add(buttonUpdateDate);
Controls.Add(checkedListBoxControl1);
Controls.Add(buttonAddDate);
Controls.Add(dateTimePicker1);
Controls.Add(dateTimePickerControl1);
Controls.Add(listBoxDates);
Controls.Add(label2);
Controls.Add(label1);
Controls.Add(buttonSave);
Controls.Add(buttonCancel);
Controls.Add(labelcity);
Controls.Add(textBoxLogin);
Controls.Add(labelLogin);
Margin = new Padding(3, 2, 3, 2);
Name = "FormAccount";
Text = "Аккаунт";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelLogin;
private TextBox textBoxLogin;
private Label labelcity;
private Button buttonCancel;
private Button buttonSave;
private OpenFileDialog openFileDialog;
private Label label1;
private Label label2;
private ListBox listBoxDates;
private PutincevLibrary.DateTimePickerControl dateTimePickerControl1;
private DateTimePicker dateTimePicker1;
private Button buttonAddDate;
private PutincevLibrary.CheckedListBoxControl checkedListBoxControl1;
private Button buttonUpdateDate;
private Button buttonDeleteDate;
}
}

View File

@@ -0,0 +1,172 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicContracts;
using Contracts.SearchModels;
using Contracts.ViewModels;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinForms
{
public partial class FormAccount : Form
{
public int? _id;
private readonly IAccountLogic _logic;
//private readonly ICityLogic _cityLogic;
private List<CityViewModel> _Cities;
private bool hasUnsavedChanges = false;
public int Id { set { _id = value; } }
public FormAccount(IAccountLogic logic, ICityLogic cityLogic)
{
InitializeComponent();
_logic = logic;
_Cities = new List<CityViewModel>();
_Cities = cityLogic.ReadList(null);
var cityNames = _Cities.Select(city => city.Name).ToList();
checkedListBoxControl1.SetCheckedListBoxValues(cityNames);
DateTime now = DateTime.Now;
dateTimePickerControl1.MaxValue = now;
dateTimePickerControl1.MinValue = now.AddYears(-10);
this.Load += FormAccount_Load;
}
private void FormAccount_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
try
{
AccountViewModel accountViewModel = _logic.ReadElement(new AccountSearchModel { Id = _id.Value });
if (accountViewModel != null)
{
textBoxLogin.Text = accountViewModel.Login;
CityViewModel selectedCity = _Cities.FirstOrDefault(city => city.Id == accountViewModel.ResidenceCityId);
if (selectedCity != null)
{
checkedListBoxControl1.CheckedItem = selectedCity.Name;
}
dateTimePickerControl1.SelectedValue = accountViewModel.AccountCreationDate;
foreach (DateTime status in accountViewModel.AuthorizationAttemptsHistory)
{
listBoxDates.Items.Add(status);
}
}
else
{
MessageBox.Show("Аккаунт с указанным ID не найден.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxLogin.Text))
{
MessageBox.Show("Заполните логин", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
if (checkedListBoxControl1.CheckedItem == null)
{
MessageBox.Show("Укажите город проживания", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
try
{
var model = new AccountBindingModel
{
Id = _id ?? 0,
Login = textBoxLogin.Text,
ResidenceCityId = _Cities.First(x => x.Name == checkedListBoxControl1.CheckedItem).Id,
AccountCreationDate = (DateTime)dateTimePickerControl1.SelectedValue,
AuthorizationAttemptsHistory = listBoxDates.Items
.Cast<DateTime>()
.Select(date => DateTime.SpecifyKind(date, DateTimeKind.Utc))
.ToList()
};
var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model);
if (!operationResult)
{
throw new Exception("Возникла ошибка при сохранении. Дополнительная информация в логах");
}
MessageBox.Show("Сохранение прошло успешно", "Успешное сохранение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (DbUpdateException ex)
{
// Получение внутреннего исключения для более подробной информации
var innerException = ex.InnerException;
MessageBox.Show($"Ошибка при обновлении базы данных: {innerException?.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonAddDate_Click(object sender, EventArgs e)
{
listBoxDates.Items.Add(dateTimePicker1.Value);
}
private void buttonUpdateDate_Click(object sender, EventArgs e)
{
if (listBoxDates.SelectedIndex != -1)
{
listBoxDates.Items[listBoxDates.SelectedIndex] = dateTimePicker1.Value;
}
else
{
MessageBox.Show("Выберите изменяемую дату", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void buttonDeleteDate_Click(object sender, EventArgs e)
{
if (listBoxDates.SelectedIndex != -1)
{
listBoxDates.Items.RemoveAt(listBoxDates.SelectedIndex);
}
else
{
MessageBox.Show("Выберите удаляемую дату", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
Close();
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
// Проверка наличия несохраненных изменений
if (hasUnsavedChanges)
{
var result = MessageBox.Show("У вас есть несохраненные изменения. Вы действительно хотите закрыть форму?", "Предупреждение", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
// Если пользователь выбирает "Нет", отмена закрытия формы
if (result == DialogResult.No)
{
e.Cancel = true;
}
}
}
}
}

View File

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

86
Lab3/WinForms/FormCities.Designer.cs generated Normal file
View File

@@ -0,0 +1,86 @@
using System.Windows.Forms;
namespace WinForms
{
partial class FormCities
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
dataGridView = new DataGridView();
NameCol = new DataGridViewTextBoxColumn();
Id = new DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Columns.AddRange(new DataGridViewColumn[] { NameCol, Id });
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 47;
dataGridView.Size = new Size(800, 356);
dataGridView.TabIndex = 0;
dataGridView.CellValueChanged += dataGridView_CellValueChanged;
dataGridView.UserDeletingRow += dataGridView_UserDeletingRow;
dataGridView.KeyUp += dataGridView_KeyUp;
//
// NameCol
//
NameCol.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
NameCol.HeaderText = "Город проживания";
NameCol.MinimumWidth = 6;
NameCol.Name = "NameCol";
//
// Id
//
Id.HeaderText = "Id";
Id.MinimumWidth = 6;
Id.Name = "Id";
Id.Visible = false;
Id.Width = 125;
//
// Formcitys
//
AutoScaleDimensions = new SizeF(8F, 19F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 356);
Controls.Add(dataGridView);
Name = "Formcitys";
Text = "Города";
Load += Formcitys_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private DataGridViewTextBoxColumn NameCol;
private DataGridViewTextBoxColumn Id;
}
}

105
Lab3/WinForms/FormCities.cs Normal file
View File

@@ -0,0 +1,105 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicContracts;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinForms
{
public partial class FormCities : Form
{
private readonly ICityLogic _logic;
private bool loading = false;
public FormCities(ICityLogic logic)
{
InitializeComponent();
_logic = logic;
}
private void LoadData()
{
loading = true;
try
{
var list = _logic.ReadList(null);
if (list != null)
{
foreach (var city in list)
{
int rowIndex = dataGridView.Rows.Add();
dataGridView.Rows[rowIndex].Cells[0].Value = city.Name;
dataGridView.Rows[rowIndex].Cells[1].Value = city.Id;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
loading = false;
}
}
private void Formcitys_Load(object sender, EventArgs e)
{
LoadData();
}
private void dataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (loading || e.RowIndex < 0 || e.ColumnIndex != 0) return;
if (dataGridView.Rows[e.RowIndex].Cells[1].Value != null && !string.IsNullOrEmpty(dataGridView.Rows[e.RowIndex].Cells[1].Value.ToString()))
{
var name = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
if (name is null) return;
_logic.Update(new CityBindingModel { Id = Convert.ToInt32(dataGridView.Rows[e.RowIndex].Cells[1].Value), Name = name.ToString() });
}
else
{
var name = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
if (name is null) return;
_logic.Create(new CityBindingModel { Id = 0, Name = name.ToString() });
int newCityId = _logic.ReadList(null).ToList().Last().Id;
dataGridView.Rows[e.RowIndex].Cells[1].Value = newCityId;
}
}
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 (!_logic.Delete(new CityBindingModel { Id = Convert.ToInt32(row.Cells[1].Value) })) continue;
}
dataGridView.Rows.Clear();
LoadData();
}
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);
}
}
}

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>

173
Lab3/WinForms/FormMain.Designer.cs generated Normal file
View File

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

261
Lab3/WinForms/FormMain.cs Normal file
View File

@@ -0,0 +1,261 @@
using PluginsConventionLibrary;
using System.Reflection;
namespace WinForms
{
public partial class FormMain : Form
{
private readonly Dictionary<string, IPluginsConvention> _plugins;
private string _selectedPlugin;
public FormMain()
{
InitializeComponent();
_plugins = new();
LoadPlugins();
_selectedPlugin = string.Empty;
}
private void LoadPlugins()
{
List<IPluginsConvention> pluginsList = GetPlugins();
foreach (var plugin in pluginsList)
{
_plugins[plugin.PluginName] = plugin;
CreateMenuItem(plugin.PluginName);
}
}
private List<IPluginsConvention> GetPlugins()
{
string currentDir = Environment.CurrentDirectory;
string pluginsDir = Directory.GetParent(currentDir).Parent.Parent.Parent.FullName + "/WinForms/Plugins";
string[] dllFiles = Directory.GetFiles(
pluginsDir,
"*.dll",
SearchOption.AllDirectories
);
List<IPluginsConvention> plugins = new();
foreach (string dllFile in dllFiles)
{
try
{
Assembly assembly = Assembly.LoadFrom(dllFile);
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
if (typeof(IPluginsConvention).IsAssignableFrom(type) && !type.IsInterface)
{
if (Activator.CreateInstance(type) is IPluginsConvention plugin)
{
plugins.Add(plugin);
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(
ex.Message
);
}
}
return plugins;
}
private void CreateMenuItem(string pluginName)
{
ToolStripMenuItem menuItem = new(pluginName);
menuItem.Click += (object? sender, EventArgs e) =>
{
UserControl userControl = _plugins[pluginName].GetControl;
if (userControl != null)
{
panelControl.Controls.Clear();
userControl.Dock = DockStyle.Fill;
_plugins[pluginName].ReloadData();
_selectedPlugin = pluginName;
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 = "PDF Files|*.pdf"
};
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 = "Excel Files|*.xlsx"
};
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 = "docx|*.docx"
};
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();
}
}

132
Lab3/WinForms/FormMain.resx Normal file
View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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