Fixes
This commit is contained in:
parent 58fe126791
commit ab5ffcbfbf
45 changed files with 4868 additions and 80 deletions

View File

@ -30,6 +30,12 @@ namespace RouteGuideContracts.ViewModels
/// </summary> /// </summary>
public int TransportId { get; set; } public int TransportId { get; set; }
/// <summary>
/// Номерной знак транспорта
/// </summary>
[DisplayName("Номер транспорта")]
public string TransportLicense { get; set; } = string.Empty;
/// <summary> /// <summary>
/// Коллекция остановок маршрута /// Коллекция остановок маршрута
/// </summary> /// </summary>

View File

@ -47,5 +47,11 @@ namespace RouteGuideContracts.ViewModels
/// Идентификатор маршрута /// Идентификатор маршрута
/// </summary> /// </summary>
public int RouteId { get; set; } public int RouteId { get; set; }
/// <summary>
/// Название маршрута
/// </summary>
[DisplayName("Маршрут")]
public string RouteName { get; set; } = string.Empty;
} }
} }

View File

@ -1,4 +1,5 @@
using System; using RouteGuideDataModels.Models;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
@ -11,7 +12,7 @@ namespace RouteGuideContracts.ViewModels
/// Модель для передачи данных пользователю /// Модель для передачи данных пользователю
/// для отображения для остановок /// для отображения для остановок
/// </summary> /// </summary>
public class StopViewModel public class StopViewModel : IStopModel
{ {
/// <summary> /// <summary>
/// Идентификатор /// Идентификатор

View File

@ -42,5 +42,11 @@ namespace RouteGuideContracts.ViewModels
/// Идентификатор водителя /// Идентификатор водителя
/// </summary> /// </summary>
public int DriverId { get; set; } public int DriverId { get; set; }
/// <summary>
/// ФИО водителя
/// </summary>
[DisplayName("ФИО водителя")]
public string DriverName { get; set; } = string.Empty;
} }
} }

View File

@ -112,7 +112,8 @@ namespace RouteGuideDatabaseImplement.Models
Id = Id, Id = Id,
Name = Name, Name = Name,
TransportId = TransportId, TransportId = TransportId,
RouteStops = RouteStops RouteStops = RouteStops,
TransportLicense = Transport.License
}; };
/// <summary> /// <summary>

View File

@ -109,7 +109,8 @@ namespace RouteGuideDatabaseImplement.Models
DepartureTime = DepartureTime, DepartureTime = DepartureTime,
ArrivalTime = ArrivalTime, ArrivalTime = ArrivalTime,
Frequency = Frequency, Frequency = Frequency,
RouteId = RouteId RouteId = RouteId,
RouteName = Route.Name
}; };
} }
} }

View File

@ -99,7 +99,8 @@ namespace RouteGuideDatabaseImplement.Models
Id = Id, Id = Id,
License = License, License = License,
Type = Type, Type = Type,
DriverId = DriverId DriverId = DriverId,
DriverName = Driver.FullName
}; };
} }
} }

View File

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

View File

@ -1,10 +0,0 @@
namespace RouteGuideView
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,140 @@
namespace RouteGuideView
{
partial class FormDriver
{
/// <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()
{
textBoxFullName = new TextBox();
textBoxPhone = new TextBox();
textBoxExperience = new TextBox();
labelFullName = new Label();
labelPhone = new Label();
labelExperience = new Label();
buttonCancel = new Button();
buttonSave = new Button();
SuspendLayout();
//
// textBoxFullName
//
textBoxFullName.Location = new Point(80, 12);
textBoxFullName.Name = "textBoxFullName";
textBoxFullName.Size = new Size(292, 23);
textBoxFullName.TabIndex = 0;
//
// textBoxPhone
//
textBoxPhone.Location = new Point(80, 41);
textBoxPhone.Name = "textBoxPhone";
textBoxPhone.Size = new Size(292, 23);
textBoxPhone.TabIndex = 1;
//
// textBoxExperience
//
textBoxExperience.Location = new Point(80, 70);
textBoxExperience.Name = "textBoxExperience";
textBoxExperience.Size = new Size(292, 23);
textBoxExperience.TabIndex = 2;
//
// labelFullName
//
labelFullName.AutoSize = true;
labelFullName.Location = new Point(12, 15);
labelFullName.Name = "labelFullName";
labelFullName.Size = new Size(37, 15);
labelFullName.TabIndex = 3;
labelFullName.Text = "ФИО:";
//
// labelPhone
//
labelPhone.AutoSize = true;
labelPhone.Location = new Point(12, 44);
labelPhone.Name = "labelPhone";
labelPhone.Size = new Size(58, 15);
labelPhone.TabIndex = 4;
labelPhone.Text = "Телефон:";
//
// labelExperience
//
labelExperience.AutoSize = true;
labelExperience.Location = new Point(12, 73);
labelExperience.Name = "labelExperience";
labelExperience.Size = new Size(40, 15);
labelExperience.TabIndex = 5;
labelExperience.Text = "Опыт:";
//
// buttonCancel
//
buttonCancel.Location = new Point(297, 106);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(75, 23);
buttonCancel.TabIndex = 6;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(216, 106);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(75, 23);
buttonSave.TabIndex = 7;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// FormDriver
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(384, 141);
Controls.Add(buttonSave);
Controls.Add(buttonCancel);
Controls.Add(labelExperience);
Controls.Add(labelPhone);
Controls.Add(labelFullName);
Controls.Add(textBoxExperience);
Controls.Add(textBoxPhone);
Controls.Add(textBoxFullName);
Name = "FormDriver";
Text = "Водитель";
Load += FormDriver_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBoxFullName;
private TextBox textBoxPhone;
private TextBox textBoxExperience;
private Label labelFullName;
private Label labelPhone;
private Label labelExperience;
private Button buttonCancel;
private Button buttonSave;
}
}

View File

@ -0,0 +1,141 @@
using Microsoft.Extensions.Logging;
using RouteGuideContracts.BindingModels;
using RouteGuideContracts.BusinessLogicsContracts;
using RouteGuideContracts.SearchModels;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RouteGuideView
{
/// <summary>
/// Форма для создания/редактирования водителей
/// </summary>
public partial class FormDriver : Form
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Бизнес-логика
/// </summary>
private readonly IDriverLogic _driverLogic;
/// <summary>
/// Идентификатор
/// </summary>
private int? _id;
/// <summary>
/// Идентификатор
/// </summary>
public int Id { set { _id = value; } }
/// <summary>
/// Конструктор
/// </summary>
public FormDriver(ILogger<FormDriver> logger, IDriverLogic driverLogic)
{
InitializeComponent();
_logger = logger;
_driverLogic = driverLogic;
}
/// <summary>
/// Загрузка информации о сущности
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormDriver_Load(object sender, EventArgs e)
{
if (!_id.HasValue)
{
return;
}
try
{
_logger.LogInformation("Получение сущности 'Водитель'");
var view = _driverLogic.ReadElement(new DriverSearchModel
{
Id = _id.Value
});
if (view != null)
{
textBoxFullName.Text = view.FullName;
textBoxPhone.Text = view.Phone;
textBoxExperience.Text = view.Experience.ToString();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения сущности 'Водитель'");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Кнопка "Сохранить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxFullName.Text))
{
MessageBox.Show("Заполните ФИО", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxPhone.Text))
{
MessageBox.Show("Заполните номер телефона", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение сущности 'Водитель'");
try
{
var model = new DriverBindingModel
{
Id = _id ?? 0,
FullName = textBoxFullName.Text,
Phone = textBoxPhone.Text,
Experience = int.TryParse(textBoxExperience.Text, out int experience) ? experience : 0
};
var operationResult = _id.HasValue ? _driverLogic.Update(model) : _driverLogic.Create(model);
if (!operationResult)
{
throw new Exception("Ошибка при сохранении сущности 'Водитель'. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение сущности 'Водитель' прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения сущности 'Водитель'");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Кнопка "Отмена"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

View File

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->

View File

@ -0,0 +1,121 @@
namespace RouteGuideView
{
partial class FormDrivers
{
/// <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();
buttonRefresh = new Button();
buttonDelete = new Button();
buttonUpdate = new Button();
buttonCreate = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(0, 0);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowTemplate.Height = 25;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(550, 361);
dataGridView.TabIndex = 6;
//
// buttonRefresh
//
buttonRefresh.Location = new Point(585, 99);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(75, 23);
buttonRefresh.TabIndex = 10;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += buttonRefresh_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(585, 70);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(75, 23);
buttonDelete.TabIndex = 9;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += buttonDelete_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(585, 41);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(75, 23);
buttonUpdate.TabIndex = 8;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonCreate
//
buttonCreate.Location = new Point(585, 12);
buttonCreate.Name = "buttonCreate";
buttonCreate.Size = new Size(75, 23);
buttonCreate.TabIndex = 7;
buttonCreate.Text = "Создать";
buttonCreate.UseVisualStyleBackColor = true;
buttonCreate.Click += buttonCreate_Click;
//
// FormDrivers
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(684, 361);
Controls.Add(buttonRefresh);
Controls.Add(buttonDelete);
Controls.Add(buttonUpdate);
Controls.Add(buttonCreate);
Controls.Add(dataGridView);
Name = "FormDrivers";
Text = "Водители";
Load += FormDrivers_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonRefresh;
private Button buttonDelete;
private Button buttonUpdate;
private Button buttonCreate;
}
}

View File

@ -0,0 +1,151 @@
using Microsoft.Extensions.Logging;
using RouteGuideContracts.BindingModels;
using RouteGuideContracts.BusinessLogicsContracts;
using System;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RouteGuideView
{
/// <summary>
/// Форма для вывода списка водителей
/// </summary>
public partial class FormDrivers : Form
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Бизнес-логика
/// </summary>
private readonly IDriverLogic _driverlogic;
/// <summary>
/// Конструктор
/// </summary>
public FormDrivers(ILogger<FormDrivers> logger, IDriverLogic driverLogic)
{
InitializeComponent();
_logger = logger;
_driverlogic = driverLogic;
}
/// <summary>
/// Загрузка данных
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormDrivers_Load(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Кнопка "Создать"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCreate_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormDriver));
if (service is FormDriver form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
/// <summary>
/// Кнопка "Изменить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormDriver));
if (service is FormDriver form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
/// <summary>
/// Кнопка "Удалить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonDelete_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление сущности 'Водитель'");
try
{
if (!_driverlogic.Delete(new DriverBindingModel { Id = id }))
{
throw new Exception("Ошибка при удалении сущности 'Водитель'. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления сущности 'Водитель'");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
/// <summary>
/// Кнопка "Обновить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonRefresh_Click(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Загрузка данных
/// </summary>
private void LoadData()
{
try
{
var list = _driverlogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["FullName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка списка водителей");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка водителей");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

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,183 @@
namespace RouteGuideView
{
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()
{
menuStrip1 = new MenuStrip();
справочникиToolStripMenuItem = new ToolStripMenuItem();
DrviversToolStripMenuItem = new ToolStripMenuItem();
TransportToolStripMenuItem = new ToolStripMenuItem();
RoutesToolStripMenuItem = new ToolStripMenuItem();
StopsToolStripMenuItem = new ToolStripMenuItem();
buttonCreate = new Button();
buttonUpdate = new Button();
buttonDelete = new Button();
buttonRefresh = new Button();
dataGridView = new DataGridView();
menuStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// menuStrip1
//
menuStrip1.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem });
menuStrip1.Location = new Point(0, 0);
menuStrip1.Name = "menuStrip1";
menuStrip1.Size = new Size(984, 24);
menuStrip1.TabIndex = 0;
menuStrip1.Text = "menuStrip1";
//
// справочникиToolStripMenuItem
//
справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { DrviversToolStripMenuItem, TransportToolStripMenuItem, RoutesToolStripMenuItem, StopsToolStripMenuItem });
справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem";
справочникиToolStripMenuItem.Size = new Size(97, 20);
справочникиToolStripMenuItem.Text = " Справочники";
//
// DrviversToolStripMenuItem
//
DrviversToolStripMenuItem.Name = "DrviversToolStripMenuItem";
DrviversToolStripMenuItem.Size = new Size(180, 22);
DrviversToolStripMenuItem.Text = "Водители";
DrviversToolStripMenuItem.Click += DrviversToolStripMenuItem_Click;
//
// TransportToolStripMenuItem
//
TransportToolStripMenuItem.Name = "TransportToolStripMenuItem";
TransportToolStripMenuItem.Size = new Size(180, 22);
TransportToolStripMenuItem.Text = "Транспорт";
TransportToolStripMenuItem.Click += TransportToolStripMenuItem_Click;
//
// RoutesToolStripMenuItem
//
RoutesToolStripMenuItem.Name = "RoutesToolStripMenuItem";
RoutesToolStripMenuItem.Size = new Size(180, 22);
RoutesToolStripMenuItem.Text = "Маршруты";
RoutesToolStripMenuItem.Click += RoutesToolStripMenuItem_Click;
//
// StopsToolStripMenuItem
//
StopsToolStripMenuItem.Name = "StopsToolStripMenuItem";
StopsToolStripMenuItem.Size = new Size(180, 22);
StopsToolStripMenuItem.Text = "Остановки";
StopsToolStripMenuItem.Click += StopsToolStripMenuItem_Click;
//
// buttonCreate
//
buttonCreate.Location = new Point(885, 37);
buttonCreate.Name = "buttonCreate";
buttonCreate.Size = new Size(75, 23);
buttonCreate.TabIndex = 1;
buttonCreate.Text = "Создать";
buttonCreate.UseVisualStyleBackColor = true;
buttonCreate.Click += buttonCreate_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(885, 66);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(75, 23);
buttonUpdate.TabIndex = 2;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(885, 95);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(75, 23);
buttonDelete.TabIndex = 3;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += buttonDelete_Click;
//
// buttonRefresh
//
buttonRefresh.Location = new Point(885, 124);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(75, 23);
buttonRefresh.TabIndex = 4;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += buttonRefresh_Click;
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(0, 24);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowTemplate.Height = 25;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(850, 337);
dataGridView.TabIndex = 5;
//
// FormMain
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(984, 361);
Controls.Add(dataGridView);
Controls.Add(buttonRefresh);
Controls.Add(buttonDelete);
Controls.Add(buttonUpdate);
Controls.Add(buttonCreate);
Controls.Add(menuStrip1);
MainMenuStrip = menuStrip1;
Name = "FormMain";
Text = "Расписание";
Load += FormMain_Load;
menuStrip1.ResumeLayout(false);
menuStrip1.PerformLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private MenuStrip menuStrip1;
private ToolStripMenuItem справочникиToolStripMenuItem;
private ToolStripMenuItem DrviversToolStripMenuItem;
private ToolStripMenuItem TransportToolStripMenuItem;
private ToolStripMenuItem RoutesToolStripMenuItem;
private ToolStripMenuItem StopsToolStripMenuItem;
private Button buttonCreate;
private Button buttonUpdate;
private Button buttonDelete;
private Button buttonRefresh;
private DataGridView dataGridView;
}
}

View File

@ -0,0 +1,204 @@
using Microsoft.Extensions.Logging;
using RouteGuideBusinessLogics.BusinessLogics;
using RouteGuideContracts.BindingModels;
using RouteGuideContracts.BusinessLogicsContracts;
namespace RouteGuideView
{
/// <summary>
/// Ôîðìà äëÿ âûâîäà ñïèñêà ðàñïèñàíèé
/// </summary>
public partial class FormMain : Form
{
/// <summary>
/// Ëîããåð
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Áèçíåñ-ëîãèêà äëÿ ðàñïèñàíèé
/// </summary>
private readonly IScheduleLogic _schedulelogic;
/// <summary>
/// Êîíñòðóêòîð
/// </summary>
/// <param name="logger"></param>
/// <param name="scheduleLogic"></param>
public FormMain(ILogger<FormMain> logger, IScheduleLogic scheduleLogic)
{
InitializeComponent();
_logger = logger;
_schedulelogic = scheduleLogic;
}
/// <summary>
/// Çàãðóçêà äàííûõ
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Ôîðìà äëÿ âûâîäà ñïèñêà âîäèòåëåé
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DrviversToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormDrivers));
if (service is FormDrivers form)
{
form.ShowDialog();
}
}
/// <summary>
/// Ôîðìà äëÿ âûâîäà ñïèñêà òðàíñïîðòà
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TransportToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormTransports));
if (service is FormTransports form)
{
form.ShowDialog();
}
}
/// <summary>
/// Ôîðìà äëÿ âûâîäà ñïèñêà ìàðøðóòîâ
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void RoutesToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormRoutes));
if (service is FormRoutes form)
{
form.ShowDialog();
}
}
/// <summary>
/// Ôîðìà äëÿ âûâîäà ñïèñêà îñòàíîâîê
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void StopsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormStops));
if (service is FormStops form)
{
form.ShowDialog();
}
}
/// <summary>
/// Êíîïêà "Ñîçäàòü"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCreate_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSchedule));
if (service is FormSchedule form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
/// <summary>
/// Êíîïêà "Èçìåíèòü"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSchedule));
if (service is FormSchedule form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
/// <summary>
/// Êíîïêà "Óäàëèòü"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonDelete_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Óäàëèòü çàïèñü?", "Âîïðîñ", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Óäàëåíèå ñóùíîñòè 'Ðàñïèñàíèå'");
try
{
if (!_schedulelogic.Delete(new ScheduleBindingModel { Id = id }))
{
throw new Exception("Îøèáêà ïðè óäàëåíèè ñóùíîñòè 'Ðàñïèñàíèå'. Äîïîëíèòåëüíàÿ èíôîðìàöèÿ â ëîãàõ.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Îøèáêà óäàëåíèÿ ñóùíîñòè 'Ðàñïèñàíèå'");
MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
/// <summary>
/// Êíîïêà "Îáíîâèòü"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonRefresh_Click(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Çàãðóçêà äàííûõ
/// </summary>
private void LoadData()
{
try
{
var list = _schedulelogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["RouteId"].Visible = false;
dataGridView.Columns["RouteName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Çàãðóçêà ñïèñêà ðàñïèñàíèé");
}
catch (Exception ex)
{
_logger.LogError(ex, "Îøèáêà çàãðóçêè ñïèñêà ðàñïèñàíèé");
MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

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="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@ -0,0 +1,211 @@
namespace RouteGuideView
{
partial class FormRoute
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
textBoxName = new TextBox();
labelName = new Label();
groupBox = new GroupBox();
buttonRefresh = new Button();
buttonDelete = new Button();
buttonUpdate = new Button();
buttonCreate = new Button();
dataGridView = new DataGridView();
ColumnId = new DataGridViewTextBoxColumn();
ColumnName = new DataGridViewTextBoxColumn();
ColumnNumber = new DataGridViewTextBoxColumn();
buttonSave = new Button();
buttonCancel = new Button();
groupBox.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// textBoxName
//
textBoxName.Location = new Point(80, 12);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(200, 23);
textBoxName.TabIndex = 0;
//
// labelName
//
labelName.AutoSize = true;
labelName.Location = new Point(12, 15);
labelName.Name = "labelName";
labelName.Size = new Size(62, 15);
labelName.TabIndex = 1;
labelName.Text = "Название:";
//
// groupBox
//
groupBox.Controls.Add(buttonRefresh);
groupBox.Controls.Add(buttonDelete);
groupBox.Controls.Add(buttonUpdate);
groupBox.Controls.Add(buttonCreate);
groupBox.Controls.Add(dataGridView);
groupBox.Location = new Point(12, 41);
groupBox.Name = "groupBox";
groupBox.Size = new Size(660, 279);
groupBox.TabIndex = 2;
groupBox.TabStop = false;
groupBox.Text = "Остановки";
//
// buttonRefresh
//
buttonRefresh.Location = new Point(558, 109);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(75, 23);
buttonRefresh.TabIndex = 18;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += buttonRefresh_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(558, 80);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(75, 23);
buttonDelete.TabIndex = 17;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += buttonDelete_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(558, 51);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(75, 23);
buttonUpdate.TabIndex = 16;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonCreate
//
buttonCreate.Location = new Point(558, 22);
buttonCreate.Name = "buttonCreate";
buttonCreate.Size = new Size(75, 23);
buttonCreate.TabIndex = 15;
buttonCreate.Text = "Добавить";
buttonCreate.UseVisualStyleBackColor = true;
buttonCreate.Click += buttonCreate_Click;
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Columns.AddRange(new DataGridViewColumn[] { ColumnId, ColumnName, ColumnNumber });
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(3, 19);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowTemplate.Height = 25;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(530, 257);
dataGridView.TabIndex = 0;
//
// ColumnId
//
ColumnId.HeaderText = "Id";
ColumnId.Name = "ColumnId";
ColumnId.ReadOnly = true;
ColumnId.Visible = false;
//
// ColumnName
//
ColumnName.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
ColumnName.HeaderText = "Остановка";
ColumnName.Name = "ColumnName";
ColumnName.ReadOnly = true;
//
// ColumnNumber
//
ColumnNumber.HeaderText = "Номер остановки";
ColumnNumber.Name = "ColumnNumber";
ColumnNumber.ReadOnly = true;
//
// buttonSave
//
buttonSave.Location = new Point(516, 326);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(75, 23);
buttonSave.TabIndex = 9;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(597, 326);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(75, 23);
buttonCancel.TabIndex = 8;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// FormRoute
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(684, 361);
Controls.Add(buttonSave);
Controls.Add(buttonCancel);
Controls.Add(groupBox);
Controls.Add(labelName);
Controls.Add(textBoxName);
Name = "FormRoute";
Text = "Маршрут";
Load += FormRoute_Load;
groupBox.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBoxName;
private Label labelName;
private GroupBox groupBox;
private DataGridView dataGridView;
private Button buttonSave;
private Button buttonCancel;
private Button buttonRefresh;
private Button buttonDelete;
private Button buttonUpdate;
private Button buttonCreate;
private DataGridViewTextBoxColumn ColumnId;
private DataGridViewTextBoxColumn ColumnName;
private DataGridViewTextBoxColumn ColumnNumber;
}
}

View File

@ -0,0 +1,273 @@
using Microsoft.Extensions.Logging;
using RouteGuideBusinessLogics.BusinessLogics;
using RouteGuideContracts.BindingModels;
using RouteGuideContracts.BusinessLogicsContracts;
using RouteGuideContracts.SearchModels;
using RouteGuideDataModels.Models;
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 RouteGuideView
{
/// <summary>
/// Форма для создания/редактирования маршрутов
/// </summary>
public partial class FormRoute : Form
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Бизнес-логика
/// </summary>
private readonly IRouteLogic _routeLogic;
/// <summary>
/// Идентификатор
/// </summary>
private int? _id;
/// <summary>
/// Идентификатор
/// </summary>
public int Id { set { _id = value; } }
/// <summary>
/// Список остановок в маршруте
/// </summary>
private Dictionary<int, (IStopModel, int)> _routeStops;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="routeLogic"></param>
public FormRoute(ILogger<FormRoute> logger, IRouteLogic routeLogic)
{
InitializeComponent();
_logger = logger;
_routeLogic = routeLogic;
_routeStops = new Dictionary<int, (IStopModel, int)>();
}
/// <summary>
/// Загрузка данных
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormRoute_Load(object sender, EventArgs e)
{
if (!_id.HasValue)
{
return;
}
try
{
_logger.LogInformation("Получение сущности 'Маршрут'");
var view = _routeLogic.ReadElement(new RouteSearchModel
{
Id = _id.Value
});
if (view != null)
{
textBoxName.Text = view.Name;
_routeStops = view.RouteStops ?? new Dictionary<int, (IStopModel, int)>();
LoadData();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения сущности 'Маршрут'");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Кнопка "Добавить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCreate_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormRouteStop));
if (service is FormRouteStop form)
{
if (form.ShowDialog() == DialogResult.OK)
{
if (form.StopModel == null)
{
return;
}
_logger.LogInformation("Добавление остановки.{Id}: {StopName} в маршрут на позицию {Number}", form.Id, form.StopModel.Name, form.Number);
if (_routeStops.ContainsKey(form.Id))
{
_routeStops[form.Id] = (form.StopModel, form.Number);
}
else
{
_routeStops.Add(form.Id, (form.StopModel, form.Number));
}
LoadData();
}
}
}
/// <summary>
/// Кнопка "Изменить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormRouteStop));
if (service is FormRouteStop form)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value);
form.Id = id;
form.Number = _routeStops[id].Item2;
if (form.ShowDialog() == DialogResult.OK)
{
if (form.StopModel == null)
{
return;
}
_logger.LogInformation("Изменение остановки.{Id}: {StopName} в маршруте на позиции {Number}", form.Id, form.StopModel.Name, form.Number);
_routeStops[form.Id] = (form.StopModel, form.Number);
LoadData();
}
}
}
}
/// <summary>
/// Кнопка "Удалить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonDelete_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
try
{
_logger.LogInformation("Удаление остановки.{Id}: {StopName} с позиции в маршруте {Number}", dataGridView.SelectedRows[0].Cells[0].Value, dataGridView.SelectedRows[0].Cells[1].Value, dataGridView.SelectedRows[0].Cells[2].Value);
_routeStops.Remove(Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value));
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления остановки.{Id}: {StopName} с позиции в маршруте {Number}", dataGridView.SelectedRows[0].Cells[0].Value, dataGridView.SelectedRows[0].Cells[1].Value, dataGridView.SelectedRows[0].Cells[2].Value);
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
LoadData();
}
}
}
/// <summary>
/// Кнопка "Обновить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonRefresh_Click(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Кнопка "Сохранить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxName.Text))
{
MessageBox.Show("Заполните название маршрута", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение сущности 'Маршрут'");
try
{
var model = new RouteBindingModel
{
Id = _id ?? 0,
Name = textBoxName.Text,
RouteStops = _routeStops
};
var operationResult = _id.HasValue ? _routeLogic.Update(model) : _routeLogic.Create(model);
if (!operationResult)
{
throw new Exception("Ошибка при сохранении сущности 'Маршрут'. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение сущности 'Маршрут' прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения сущности 'Маршрут'");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Кнопка "Отмена"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
/// <summary>
/// Загрузка данных
/// </summary>
private void LoadData()
{
_logger.LogInformation("Загрузка списка остановок в маршруте");
try
{
if (_routeStops != null)
{
dataGridView.Rows.Clear();
foreach (var rs in _routeStops)
{
dataGridView.Rows.Add(new object[]
{
rs.Key,
rs.Value.Item1.Name,
rs.Value.Item2
});
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка остановок в маршруте");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

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

View File

@ -0,0 +1,118 @@
namespace RouteGuideView
{
partial class FormRouteStop
{
/// <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()
{
comboBoxStop = new ComboBox();
textBoxNumber = new TextBox();
labelStop = new Label();
labelNumber = new Label();
buttonCancel = new Button();
buttonSave = new Button();
SuspendLayout();
//
// comboBoxStop
//
comboBoxStop.FormattingEnabled = true;
comboBoxStop.Location = new Point(80, 7);
comboBoxStop.Name = "comboBoxStop";
comboBoxStop.Size = new Size(292, 23);
comboBoxStop.TabIndex = 0;
//
// textBoxNumber
//
textBoxNumber.Location = new Point(80, 41);
textBoxNumber.Name = "textBoxNumber";
textBoxNumber.Size = new Size(292, 23);
textBoxNumber.TabIndex = 1;
//
// labelStop
//
labelStop.AutoSize = true;
labelStop.Location = new Point(12, 15);
labelStop.Name = "labelStop";
labelStop.Size = new Size(68, 15);
labelStop.TabIndex = 2;
labelStop.Text = "Остановка:";
//
// labelNumber
//
labelNumber.AutoSize = true;
labelNumber.Location = new Point(12, 44);
labelNumber.Name = "labelNumber";
labelNumber.Size = new Size(48, 15);
labelNumber.TabIndex = 3;
labelNumber.Text = "Номер:";
//
// buttonCancel
//
buttonCancel.Location = new Point(297, 76);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(75, 23);
buttonCancel.TabIndex = 4;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(216, 76);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(75, 23);
buttonSave.TabIndex = 5;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// FormRouteStop
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(384, 111);
Controls.Add(buttonSave);
Controls.Add(buttonCancel);
Controls.Add(labelNumber);
Controls.Add(labelStop);
Controls.Add(textBoxNumber);
Controls.Add(comboBoxStop);
Name = "FormRouteStop";
Text = "Остановка маршрута";
ResumeLayout(false);
PerformLayout();
}
#endregion
private ComboBox comboBoxStop;
private TextBox textBoxNumber;
private Label labelStop;
private Label labelNumber;
private Button buttonCancel;
private Button buttonSave;
}
}

View File

@ -0,0 +1,124 @@
using RouteGuideContracts.BusinessLogicsContracts;
using RouteGuideContracts.ViewModels;
using RouteGuideDataModels.Models;
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 RouteGuideView
{
/// <summary>
/// Форма для привязки остановки к маршруту
/// </summary>
public partial class FormRouteStop : Form
{
/// <summary>
/// Список остановок
/// </summary>
private readonly List<StopViewModel>? _list;
/// <summary>
/// Идентификатор остановки
/// </summary>
public int Id
{
get
{
return Convert.ToInt32(comboBoxStop.SelectedValue);
}
set
{
comboBoxStop.SelectedValue = value;
}
}
/// <summary>
/// Сущность "Остановка"
/// </summary>
public IStopModel? StopModel
{
get
{
if (_list == null)
{
return null;
}
foreach (var elem in _list)
{
if (elem.Id == Id)
{
return elem;
}
}
return null;
}
}
/// <summary>
/// Номер остановки в маршруте
/// </summary>
public int Number
{
get { return Convert.ToInt32(textBoxNumber.Text); }
set { textBoxNumber.Text = value.ToString(); }
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="stopLogic"></param>
public FormRouteStop(IStopLogic stopLogic)
{
InitializeComponent();
// Загрузка списка остановок для ComboBoxStop
_list = stopLogic.ReadList(null);
if (_list != null)
{
comboBoxStop.DisplayMember = "Name";
comboBoxStop.ValueMember = "Id";
comboBoxStop.DataSource = _list;
comboBoxStop.SelectedItem = null;
}
}
/// <summary>
/// Кнопка "Сохранить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSave_Click(object sender, EventArgs e)
{
if (comboBoxStop.SelectedValue == null)
{
MessageBox.Show("Выберите остановку", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxNumber.Text))
{
MessageBox.Show("Заполните номер остановки", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
DialogResult = DialogResult.OK;
Close();
}
/// <summary>
/// Кнопка "Отмена"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

View File

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

View File

@ -0,0 +1,121 @@
namespace RouteGuideView
{
partial class FormRoutes
{
/// <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();
buttonRefresh = new Button();
buttonDelete = new Button();
buttonUpdate = new Button();
buttonCreate = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(0, 0);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowTemplate.Height = 25;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(550, 361);
dataGridView.TabIndex = 7;
//
// buttonRefresh
//
buttonRefresh.Location = new Point(585, 99);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(75, 23);
buttonRefresh.TabIndex = 14;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += buttonRefresh_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(585, 70);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(75, 23);
buttonDelete.TabIndex = 13;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += buttonDelete_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(585, 41);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(75, 23);
buttonUpdate.TabIndex = 12;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonCreate
//
buttonCreate.Location = new Point(585, 12);
buttonCreate.Name = "buttonCreate";
buttonCreate.Size = new Size(75, 23);
buttonCreate.TabIndex = 11;
buttonCreate.Text = "Создать";
buttonCreate.UseVisualStyleBackColor = true;
buttonCreate.Click += buttonCreate_Click;
//
// FormRoutes
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(684, 361);
Controls.Add(buttonRefresh);
Controls.Add(buttonDelete);
Controls.Add(buttonUpdate);
Controls.Add(buttonCreate);
Controls.Add(dataGridView);
Name = "FormRoutes";
Text = "Маршруты";
Load += FormRoutes_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonRefresh;
private Button buttonDelete;
private Button buttonUpdate;
private Button buttonCreate;
}
}

View File

@ -0,0 +1,155 @@
using Microsoft.Extensions.Logging;
using RouteGuideBusinessLogics.BusinessLogics;
using RouteGuideContracts.BindingModels;
using RouteGuideContracts.BusinessLogicsContracts;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RouteGuideView
{
/// <summary>
/// Форма для вывода списка маршрутов
/// </summary>
public partial class FormRoutes : Form
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Бизнес-логика
/// </summary>
private readonly IRouteLogic _routelogic;
/// <summary>
/// Конструктор
/// </summary>
public FormRoutes(ILogger<FormRoutes> logger, IRouteLogic routeLogic)
{
InitializeComponent();
_logger = logger;
_routelogic = routeLogic;
}
/// <summary>
/// Загрузка данных
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormRoutes_Load(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Кнопка "Создать"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCreate_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormRoute));
if (service is FormRoute form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
/// <summary>
/// Кнопка "Изменить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormRoute));
if (service is FormRoute form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
/// <summary>
/// Кнопка "Удалить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonDelete_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление сущности 'Маршрут'");
try
{
if (!_routelogic.Delete(new RouteBindingModel { Id = id }))
{
throw new Exception("Ошибка при удалении сущности 'Маршрут'. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления сущности 'Маршрут'");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
/// <summary>
/// Кнопка "Обновить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonRefresh_Click(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Загрузка данных
/// </summary>
private void LoadData()
{
try
{
var list = _routelogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["RouteStops"].Visible = false;
dataGridView.Columns["Name"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка списка маршрутов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка маршрутов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

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,189 @@
namespace RouteGuideView
{
partial class FormSchedule
{
/// <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()
{
dateTimePickerDate = new DateTimePicker();
dateTimePickerDepartureTime = new DateTimePicker();
dateTimePickerArrivalTime = new DateTimePicker();
dateTimePickerFrequency = new DateTimePicker();
comboBoxRoute = new ComboBox();
buttonSave = new Button();
buttonCancel = new Button();
labelRoute = new Label();
labelDate = new Label();
labelDeparture = new Label();
labelArrival = new Label();
labelFrequency = new Label();
SuspendLayout();
//
// dateTimePickerDate
//
dateTimePickerDate.Location = new Point(101, 41);
dateTimePickerDate.Name = "dateTimePickerDate";
dateTimePickerDate.Size = new Size(271, 23);
dateTimePickerDate.TabIndex = 0;
//
// dateTimePickerDepartureTime
//
dateTimePickerDepartureTime.Format = DateTimePickerFormat.Time;
dateTimePickerDepartureTime.Location = new Point(101, 70);
dateTimePickerDepartureTime.Name = "dateTimePickerDepartureTime";
dateTimePickerDepartureTime.Size = new Size(271, 23);
dateTimePickerDepartureTime.TabIndex = 1;
//
// dateTimePickerArrivalTime
//
dateTimePickerArrivalTime.Format = DateTimePickerFormat.Time;
dateTimePickerArrivalTime.Location = new Point(101, 99);
dateTimePickerArrivalTime.Name = "dateTimePickerArrivalTime";
dateTimePickerArrivalTime.Size = new Size(271, 23);
dateTimePickerArrivalTime.TabIndex = 2;
//
// dateTimePickerFrequency
//
dateTimePickerFrequency.Format = DateTimePickerFormat.Time;
dateTimePickerFrequency.Location = new Point(101, 128);
dateTimePickerFrequency.Name = "dateTimePickerFrequency";
dateTimePickerFrequency.Size = new Size(271, 23);
dateTimePickerFrequency.TabIndex = 3;
//
// comboBoxRoute
//
comboBoxRoute.FormattingEnabled = true;
comboBoxRoute.Location = new Point(101, 12);
comboBoxRoute.Name = "comboBoxRoute";
comboBoxRoute.Size = new Size(271, 23);
comboBoxRoute.TabIndex = 4;
//
// buttonSave
//
buttonSave.Location = new Point(216, 164);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(75, 23);
buttonSave.TabIndex = 7;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(297, 164);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(75, 23);
buttonCancel.TabIndex = 6;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// labelRoute
//
labelRoute.AutoSize = true;
labelRoute.Location = new Point(12, 15);
labelRoute.Name = "labelRoute";
labelRoute.Size = new Size(63, 15);
labelRoute.TabIndex = 8;
labelRoute.Text = "Маршрут:";
//
// labelDate
//
labelDate.AutoSize = true;
labelDate.Location = new Point(12, 47);
labelDate.Name = "labelDate";
labelDate.Size = new Size(35, 15);
labelDate.TabIndex = 9;
labelDate.Text = "Дата:";
//
// labelDeparture
//
labelDeparture.AutoSize = true;
labelDeparture.Location = new Point(12, 76);
labelDeparture.Name = "labelDeparture";
labelDeparture.Size = new Size(83, 15);
labelDeparture.TabIndex = 10;
labelDeparture.Text = "Отправление:";
//
// labelArrival
//
labelArrival.AutoSize = true;
labelArrival.Location = new Point(12, 105);
labelArrival.Name = "labelArrival";
labelArrival.Size = new Size(67, 15);
labelArrival.TabIndex = 11;
labelArrival.Text = "Прибытие:";
//
// labelFrequency
//
labelFrequency.AutoSize = true;
labelFrequency.Font = new Font("Segoe UI", 8.25F, FontStyle.Regular, GraphicsUnit.Point);
labelFrequency.Location = new Point(12, 135);
labelFrequency.Name = "labelFrequency";
labelFrequency.Size = new Size(95, 13);
labelFrequency.TabIndex = 12;
labelFrequency.Text = "Периодичность:";
//
// FormSchedule
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(384, 200);
Controls.Add(labelFrequency);
Controls.Add(labelArrival);
Controls.Add(labelDeparture);
Controls.Add(labelDate);
Controls.Add(labelRoute);
Controls.Add(buttonSave);
Controls.Add(buttonCancel);
Controls.Add(comboBoxRoute);
Controls.Add(dateTimePickerFrequency);
Controls.Add(dateTimePickerArrivalTime);
Controls.Add(dateTimePickerDepartureTime);
Controls.Add(dateTimePickerDate);
Name = "FormSchedule";
Text = "Расписание";
Load += FormSchedule_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private DateTimePicker dateTimePickerDate;
private DateTimePicker dateTimePickerDepartureTime;
private DateTimePicker dateTimePickerArrivalTime;
private DateTimePicker dateTimePickerFrequency;
private ComboBox comboBoxRoute;
private Button buttonSave;
private Button buttonCancel;
private Label labelRoute;
private Label labelDate;
private Label labelDeparture;
private Label labelArrival;
private Label labelFrequency;
}
}

View File

@ -0,0 +1,176 @@
using Microsoft.Extensions.Logging;
using RouteGuideBusinessLogics.BusinessLogics;
using RouteGuideContracts.BindingModels;
using RouteGuideContracts.BusinessLogicsContracts;
using RouteGuideContracts.SearchModels;
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 RouteGuideView
{
/// <summary>
/// Форма для создания/редактирования расписания
/// </summary>
public partial class FormSchedule : Form
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Бизнес-логика для расписаний
/// </summary>
private readonly IScheduleLogic _scheduleLogic;
/// <summary>
/// Бизнес-логика для маршрутов
/// </summary>
private readonly IRouteLogic _routeLogic;
/// <summary>
/// Идентификатор
/// </summary>
private int? _id;
/// <summary>
/// Идентификатор
/// </summary>
public int Id { set { _id = value; } }
/// <summary>
/// Констурктор
/// </summary>
/// <param name="logger"></param>
/// <param name="scheduleLogic"></param>
/// <param name="routeLogic"></param>
public FormSchedule(ILogger<FormSchedule> logger, IScheduleLogic scheduleLogic, IRouteLogic routeLogic)
{
InitializeComponent();
_logger = logger;
_scheduleLogic = scheduleLogic;
_routeLogic = routeLogic;
}
/// <summary>
/// Загрузка данных
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormSchedule_Load(object sender, EventArgs e)
{
try
{
// Загрузка маршрутов для ComboBoxRoute
_logger.LogInformation("Загрузка списка маршрутов");
var list = _routeLogic.ReadList(null);
if (list != null)
{
comboBoxRoute.DisplayMember = "Name";
comboBoxRoute.ValueMember = "Id";
comboBoxRoute.DataSource = list;
comboBoxRoute.SelectedItem = null;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка маршрутов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
if (!_id.HasValue)
{
return;
}
try
{
// Заполнение полей
_logger.LogInformation("Получение сущности 'Расписание'");
var view = _scheduleLogic.ReadElement(new ScheduleSearchModel
{
Id = _id.Value
});
if (view != null)
{
comboBoxRoute.SelectedItem = view.RouteId;
dateTimePickerDate.Value = view.Date;
dateTimePickerDepartureTime.Value = view.DepartureTime;
dateTimePickerArrivalTime.Value = view.ArrivalTime;
dateTimePickerFrequency.Value = view.Frequency;
}
}
catch (Exception ex1)
{
_logger.LogError(ex1, "Ошибка получения сущности 'Расписание'");
MessageBox.Show(ex1.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Кнопка "Сохранить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSave_Click(object sender, EventArgs e)
{
if (comboBoxRoute.SelectedValue == null)
{
MessageBox.Show("Выберите маршрут", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (dateTimePickerDepartureTime.Value >= dateTimePickerArrivalTime.Value)
{
MessageBox.Show("Время прибытия должно опережать время отправления", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение сущности 'Расписание'");
try
{
var model = new ScheduleBindingModel
{
Id = _id ?? 0,
Date = dateTimePickerDate.Value,
DepartureTime = dateTimePickerDepartureTime.Value,
ArrivalTime = dateTimePickerArrivalTime.Value,
Frequency = dateTimePickerFrequency.Value,
RouteId = Convert.ToInt32(comboBoxRoute.SelectedValue)
};
var operationResult = _id.HasValue ? _scheduleLogic.Update(model) : _scheduleLogic.Create(model);
if (!operationResult)
{
throw new Exception("Ошибка при сохранении сущности 'Расписание'. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение сущности 'Расписание' прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения сущности 'Расписание'");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Кнопка "Отмена"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

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,140 @@
namespace RouteGuideView
{
partial class FormStop
{
/// <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()
{
buttonSave = new Button();
buttonCancel = new Button();
labelNumber = new Label();
labelStreet = new Label();
labelFullName = new Label();
textBoxNumber = new TextBox();
textBoxStreet = new TextBox();
textBoxName = new TextBox();
SuspendLayout();
//
// buttonSave
//
buttonSave.Location = new Point(216, 106);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(75, 23);
buttonSave.TabIndex = 15;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(297, 106);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(75, 23);
buttonCancel.TabIndex = 14;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// labelNumber
//
labelNumber.AutoSize = true;
labelNumber.Location = new Point(12, 73);
labelNumber.Name = "labelNumber";
labelNumber.Size = new Size(34, 15);
labelNumber.TabIndex = 13;
labelNumber.Text = "Дом:";
//
// labelStreet
//
labelStreet.AutoSize = true;
labelStreet.Location = new Point(12, 44);
labelStreet.Name = "labelStreet";
labelStreet.Size = new Size(44, 15);
labelStreet.TabIndex = 12;
labelStreet.Text = "Улица:";
//
// labelFullName
//
labelFullName.AutoSize = true;
labelFullName.Location = new Point(12, 15);
labelFullName.Name = "labelFullName";
labelFullName.Size = new Size(62, 15);
labelFullName.TabIndex = 11;
labelFullName.Text = "Название:";
//
// textBoxNumber
//
textBoxNumber.Location = new Point(80, 70);
textBoxNumber.Name = "textBoxNumber";
textBoxNumber.Size = new Size(292, 23);
textBoxNumber.TabIndex = 10;
//
// textBoxStreet
//
textBoxStreet.Location = new Point(80, 41);
textBoxStreet.Name = "textBoxStreet";
textBoxStreet.Size = new Size(292, 23);
textBoxStreet.TabIndex = 9;
//
// textBoxName
//
textBoxName.Location = new Point(80, 12);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(292, 23);
textBoxName.TabIndex = 8;
//
// FormStop
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(384, 141);
Controls.Add(buttonSave);
Controls.Add(buttonCancel);
Controls.Add(labelNumber);
Controls.Add(labelStreet);
Controls.Add(labelFullName);
Controls.Add(textBoxNumber);
Controls.Add(textBoxStreet);
Controls.Add(textBoxName);
Name = "FormStop";
Text = "Остановка";
Load += FormStop_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private Button buttonSave;
private Button buttonCancel;
private Label labelNumber;
private Label labelStreet;
private Label labelFullName;
private TextBox textBoxNumber;
private TextBox textBoxStreet;
private TextBox textBoxName;
}
}

View File

@ -0,0 +1,148 @@
using Microsoft.Extensions.Logging;
using RouteGuideBusinessLogics.BusinessLogics;
using RouteGuideContracts.BindingModels;
using RouteGuideContracts.BusinessLogicsContracts;
using RouteGuideContracts.SearchModels;
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 RouteGuideView
{
/// <summary>
/// Форма для создания/редактирования остановок
/// </summary>
public partial class FormStop : Form
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Бизнес-логика
/// </summary>
private readonly IStopLogic _stopLogic;
/// <summary>
/// Идентификатор
/// </summary>
private int? _id;
/// <summary>
/// Идентификатор
/// </summary>
public int Id { set { _id = value; } }
/// <summary>
/// Конструктор
/// </summary>
public FormStop(ILogger<FormStop> logger, IStopLogic stopLogic)
{
InitializeComponent();
_logger = logger;
_stopLogic = stopLogic;
}
/// <summary>
/// Загрузка информации о сущности
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormStop_Load(object sender, EventArgs e)
{
if (!_id.HasValue)
{
return;
}
try
{
_logger.LogInformation("Получение сущности 'Остановка'");
var view = _stopLogic.ReadElement(new StopSearchModel
{
Id = _id.Value
});
if (view != null)
{
textBoxName.Text = view.Name;
textBoxStreet.Text = view.Street;
textBoxNumber.Text = view.Number.ToString();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения сущности 'Остановка'");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Кнопка "Сохранить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxName.Text))
{
MessageBox.Show("Заполните название остановки", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxStreet.Text))
{
MessageBox.Show("Заполните название улицы", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxNumber.Text))
{
MessageBox.Show("Заполните номер дома", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение сущности 'Остановка'");
try
{
var model = new StopBindingModel
{
Id = _id ?? 0,
Name = textBoxName.Text,
Street = textBoxStreet.Text,
Number = int.TryParse(textBoxNumber.Text, out int number) ? number : 1
};
var operationResult = _id.HasValue ? _stopLogic.Update(model) : _stopLogic.Create(model);
if (!operationResult)
{
throw new Exception("Ошибка при сохранении сущности 'Остановка'. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение сущности 'Остановка' прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения сущности 'Остановка'");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Кнопка "Отмена"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

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,121 @@
namespace RouteGuideView
{
partial class FormStops
{
/// <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();
buttonRefresh = new Button();
buttonDelete = new Button();
buttonUpdate = new Button();
buttonCreate = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(0, 0);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowTemplate.Height = 25;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(550, 361);
dataGridView.TabIndex = 7;
//
// buttonRefresh
//
buttonRefresh.Location = new Point(585, 99);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(75, 23);
buttonRefresh.TabIndex = 14;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += buttonRefresh_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(585, 70);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(75, 23);
buttonDelete.TabIndex = 13;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += buttonDelete_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(585, 41);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(75, 23);
buttonUpdate.TabIndex = 12;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonCreate
//
buttonCreate.Location = new Point(585, 12);
buttonCreate.Name = "buttonCreate";
buttonCreate.Size = new Size(75, 23);
buttonCreate.TabIndex = 11;
buttonCreate.Text = "Создать";
buttonCreate.UseVisualStyleBackColor = true;
buttonCreate.Click += buttonCreate_Click;
//
// FormStops
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(684, 361);
Controls.Add(buttonRefresh);
Controls.Add(buttonDelete);
Controls.Add(buttonUpdate);
Controls.Add(buttonCreate);
Controls.Add(dataGridView);
Name = "FormStops";
Text = "Остановки";
Load += FormStops_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonRefresh;
private Button buttonDelete;
private Button buttonUpdate;
private Button buttonCreate;
}
}

View File

@ -0,0 +1,153 @@
using Microsoft.Extensions.Logging;
using RouteGuideBusinessLogics.BusinessLogics;
using RouteGuideContracts.BindingModels;
using RouteGuideContracts.BusinessLogicsContracts;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RouteGuideView
{
/// <summary>
/// Форма для вывода списка остановок
/// </summary>
public partial class FormStops : Form
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Бизнес-логика
/// </summary>
private readonly IStopLogic _stoplogic;
/// <summary>
/// Конструктор
/// </summary>
public FormStops(ILogger<FormStops> logger, IStopLogic stopLogic)
{
InitializeComponent();
_logger = logger;
_stoplogic = stopLogic;
}
/// <summary>
/// Загрузка данных
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormStops_Load(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Кнопка "Создать"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCreate_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormStop));
if (service is FormStop form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
/// <summary>
/// Кнопка "Изменить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormStop));
if (service is FormStop form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonDelete_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление сущности 'Остановка'");
try
{
if (!_stoplogic.Delete(new StopBindingModel { Id = id }))
{
throw new Exception("Ошибка при удалении сущности 'Остановка'. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления сущности 'Остановка'");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
/// <summary>
/// Кнопка "Обновить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonRefresh_Click(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Загрузка данных
/// </summary>
private void LoadData()
{
try
{
var list = _stoplogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
}
_logger.LogInformation("Загрузка списка остановок");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка остановок");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

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,164 @@
namespace RouteGuideView
{
partial class FormTransport
{
/// <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()
{
comboBoxType = new ComboBox();
comboBoxDriver = new ComboBox();
textBoxLicense = new TextBox();
textBoxCapacity = new TextBox();
buttonCancel = new Button();
buttonSave = new Button();
labelType = new Label();
labelDriver = new Label();
labelLicense = new Label();
labelCapacity = new Label();
SuspendLayout();
//
// comboBoxType
//
comboBoxType.FormattingEnabled = true;
comboBoxType.Location = new Point(101, 12);
comboBoxType.Name = "comboBoxType";
comboBoxType.Size = new Size(271, 23);
comboBoxType.TabIndex = 0;
//
// comboBoxDriver
//
comboBoxDriver.FormattingEnabled = true;
comboBoxDriver.Location = new Point(101, 41);
comboBoxDriver.Name = "comboBoxDriver";
comboBoxDriver.Size = new Size(271, 23);
comboBoxDriver.TabIndex = 1;
//
// textBoxLicense
//
textBoxLicense.Location = new Point(101, 70);
textBoxLicense.Name = "textBoxLicense";
textBoxLicense.Size = new Size(271, 23);
textBoxLicense.TabIndex = 2;
//
// textBoxCapacity
//
textBoxCapacity.Location = new Point(101, 99);
textBoxCapacity.Name = "textBoxCapacity";
textBoxCapacity.Size = new Size(271, 23);
textBoxCapacity.TabIndex = 3;
//
// buttonCancel
//
buttonCancel.Location = new Point(297, 135);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(75, 23);
buttonCancel.TabIndex = 4;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(216, 135);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(75, 23);
buttonSave.TabIndex = 5;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// labelType
//
labelType.AutoSize = true;
labelType.Location = new Point(12, 15);
labelType.Name = "labelType";
labelType.Size = new Size(30, 15);
labelType.TabIndex = 6;
labelType.Text = "Тип:";
//
// labelDriver
//
labelDriver.AutoSize = true;
labelDriver.Location = new Point(12, 44);
labelDriver.Name = "labelDriver";
labelDriver.Size = new Size(61, 15);
labelDriver.TabIndex = 7;
labelDriver.Text = "Водитель:";
//
// labelLicense
//
labelLicense.AutoSize = true;
labelLicense.Location = new Point(12, 73);
labelLicense.Name = "labelLicense";
labelLicense.Size = new Size(48, 15);
labelLicense.TabIndex = 8;
labelLicense.Text = "Номер:";
//
// labelCapacity
//
labelCapacity.AutoSize = true;
labelCapacity.Location = new Point(12, 102);
labelCapacity.Name = "labelCapacity";
labelCapacity.Size = new Size(83, 15);
labelCapacity.TabIndex = 9;
labelCapacity.Text = "Вместимость:";
//
// FormTransport
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(384, 171);
Controls.Add(labelCapacity);
Controls.Add(labelLicense);
Controls.Add(labelDriver);
Controls.Add(labelType);
Controls.Add(buttonSave);
Controls.Add(buttonCancel);
Controls.Add(textBoxCapacity);
Controls.Add(textBoxLicense);
Controls.Add(comboBoxDriver);
Controls.Add(comboBoxType);
Name = "FormTransport";
Text = "FormTransport";
Load += FormTransport_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private ComboBox comboBoxType;
private ComboBox comboBoxDriver;
private TextBox textBoxLicense;
private TextBox textBoxCapacity;
private Button buttonCancel;
private Button buttonSave;
private Label labelType;
private Label labelDriver;
private Label labelLicense;
private Label labelCapacity;
}
}

View File

@ -0,0 +1,191 @@
using Microsoft.Extensions.Logging;
using RouteGuideBusinessLogics.BusinessLogics;
using RouteGuideContracts.BindingModels;
using RouteGuideContracts.BusinessLogicsContracts;
using RouteGuideContracts.SearchModels;
using RouteGuideDataModels.Enums;
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 RouteGuideView
{
/// <summary>
/// Форма для создания/редактирования транспорта
/// </summary>
public partial class FormTransport : Form
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Бизнес-логика для транспорта
/// </summary>
private readonly ITransportLogic _transportLogic;
/// <summary>
/// Бизнес-логика для водителей
/// </summary>
private readonly IDriverLogic _driverLogic;
/// <summary>
/// Идентификатор
/// </summary>
private int? _id;
/// <summary>
/// Идентификатор
/// </summary>
public int Id { set { _id = value; } }
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="transportLogic"></param>
/// <param name="driverLogic"></param>
public FormTransport(ILogger<FormTransport> logger, ITransportLogic transportLogic, IDriverLogic driverLogic)
{
InitializeComponent();
_logger = logger;
_transportLogic = transportLogic;
_driverLogic = driverLogic;
}
/// <summary>
/// Загрузка данных
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormTransport_Load(object sender, EventArgs e)
{
// Загрузка типов транспорта для ComboBoxType
foreach (TransportType type in Enum.GetValues(typeof(TransportType)))
{
comboBoxType.Items.Add(type);
}
try
{
// Загрузка водителей для ComboBoxDriver
_logger.LogInformation("Загрузка списка водителей");
var list = _driverLogic.ReadList(null);
if (list != null)
{
comboBoxDriver.DisplayMember = "FullName";
comboBoxDriver.ValueMember = "Id";
comboBoxDriver.DataSource = list;
comboBoxDriver.SelectedItem = null;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка водителей");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
if (!_id.HasValue)
{
return;
}
try
{
// Заполнение полей
_logger.LogInformation("Получение сущности 'Транспорт'");
var view = _transportLogic.ReadElement(new TransportSearchModel
{
Id = _id.Value
});
if (view != null)
{
textBoxLicense.Text = view.License;
textBoxCapacity.Text = view.Capacity.ToString();
comboBoxDriver.SelectedItem = view.DriverId;
comboBoxType.SelectedItem = view.Type;
}
}
catch (Exception ex1)
{
_logger.LogError(ex1, "Ошибка получения сущности 'Водитель'");
MessageBox.Show(ex1.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Кнопка "Сохранить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSave_Click(object sender, EventArgs e)
{
if (comboBoxType.SelectedValue == null)
{
MessageBox.Show("Выберите тип транспорта", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxDriver.SelectedValue == null)
{
MessageBox.Show("Выберите водителя", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxLicense.Text))
{
MessageBox.Show("Заполните номер транспорта", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxCapacity.Text))
{
MessageBox.Show("Заполните вместимость", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение сущности 'Транспорт'");
try
{
var model = new TransportBindingModel
{
Id = _id ?? 0,
License = textBoxLicense.Text,
Type = (TransportType)comboBoxType.SelectedValue,
Capacity = int.TryParse(textBoxCapacity.Text, out var capacity) ? capacity : 1,
DriverId = Convert.ToInt32(comboBoxDriver.SelectedValue)
};
var operationResult = _id.HasValue ? _transportLogic.Update(model) : _transportLogic.Create(model);
if (!operationResult)
{
throw new Exception("Ошибка при сохранении сущности 'Транспорт'. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение сущности 'Транспорт' прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения сущности 'Транспорт'");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Кнопка "Отмена"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

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,121 @@
namespace RouteGuideView
{
partial class FormTransports
{
/// <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();
buttonRefresh = new Button();
buttonDelete = new Button();
buttonUpdate = new Button();
buttonCreate = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(0, 0);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowTemplate.Height = 25;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(550, 361);
dataGridView.TabIndex = 7;
//
// buttonRefresh
//
buttonRefresh.Location = new Point(585, 99);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(75, 23);
buttonRefresh.TabIndex = 14;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += buttonRefresh_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(585, 70);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(75, 23);
buttonDelete.TabIndex = 13;
buttonDelete.Text = "Удалить";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += buttonDelete_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(585, 41);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(75, 23);
buttonUpdate.TabIndex = 12;
buttonUpdate.Text = "Изменить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonCreate
//
buttonCreate.Location = new Point(585, 12);
buttonCreate.Name = "buttonCreate";
buttonCreate.Size = new Size(75, 23);
buttonCreate.TabIndex = 11;
buttonCreate.Text = "Создать";
buttonCreate.UseVisualStyleBackColor = true;
buttonCreate.Click += buttonCreate_Click;
//
// FormTransports
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(684, 361);
Controls.Add(buttonRefresh);
Controls.Add(buttonDelete);
Controls.Add(buttonUpdate);
Controls.Add(buttonCreate);
Controls.Add(dataGridView);
Name = "FormTransports";
Text = "Транспорт";
Load += FormTransports_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonRefresh;
private Button buttonDelete;
private Button buttonUpdate;
private Button buttonCreate;
}
}

View File

@ -0,0 +1,154 @@
using Microsoft.Extensions.Logging;
using RouteGuideBusinessLogics.BusinessLogics;
using RouteGuideContracts.BindingModels;
using RouteGuideContracts.BusinessLogicsContracts;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RouteGuideView
{
/// <summary>
/// Форма для вывода списка транспорта
/// </summary>
public partial class FormTransports : Form
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Бизнес-логика
/// </summary>
private readonly ITransportLogic _transportlogic;
/// <summary>
/// Конструктор
/// </summary>
public FormTransports(ILogger<FormTransports> logger, ITransportLogic transportLogic)
{
InitializeComponent();
_logger = logger;
_transportlogic = transportLogic;
}
/// <summary>
/// Загрузка данных
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormTransports_Load(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Кнопка "Создать"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCreate_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormTransport));
if (service is FormTransport form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
/// <summary>
/// Кнопка "Изменить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormTransport));
if (service is FormTransport form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
/// <summary>
/// Кнопка "Удалить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonDelete_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление сущности 'Транспорт'");
try
{
if (!_transportlogic.Delete(new TransportBindingModel { Id = id }))
{
throw new Exception("Ошибка при удалении сущности 'Транспорт'. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления сущности 'Транспорт'");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
/// <summary>
/// Кнопка "Обновить"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonRefresh_Click(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Загрузка данных
/// </summary>
private void LoadData()
{
try
{
var list = _transportlogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["DriverId"].Visible = false;
}
_logger.LogInformation("Загрузка списка транспорта");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка транспорта");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

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

View File

@ -1,7 +1,21 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using RouteGuideBusinessLogics.BusinessLogics;
using RouteGuideContracts.BusinessLogicsContracts;
using RouteGuideContracts.StoragesContracts;
using RouteGuideDatabaseImplement.Implements;
namespace RouteGuideView namespace RouteGuideView
{ {
internal static class Program internal static class Program
{ {
/// <summary>
/// IoC-êîíòåéíåð
/// </summary>
private static ServiceProvider? _serviceProvider;
public static ServiceProvider? ServiceProvider => _serviceProvider;
/// <summary> /// <summary>
/// The main entry point for the application. /// The main entry point for the application.
/// </summary> /// </summary>
@ -11,7 +25,53 @@ namespace RouteGuideView
// To customize application configuration such as set high DPI settings or default font, // To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration. // see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize(); ApplicationConfiguration.Initialize();
Application.Run(new Form1());
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
}
/// <summary>
/// Êîíôèãóðàöèÿ ñåðâèñîâ
/// </summary>
/// <param name="services"></param>
private static void ConfigureServices(ServiceCollection services)
{
// Ëîããåð
services.AddLogging(option =>
{
option.SetMinimumLevel(LogLevel.Information);
option.AddNLog("nlog.config");
});
// IoC-êîíòåéíåð, õðàíèëèùà
services.AddTransient<IDriverStorage, DriverStorage>();
services.AddTransient<ITransportStorage, TransportStorage>();
services.AddTransient<IRouteStorage, RouteStorage>();
services.AddTransient<IStopStorage, StopStorage>();
services.AddTransient<IScheduleStorage, ScheduleStorage>();
// IoC-êîíòåéíåð, áèçíåñ-ëîãèêà
services.AddTransient<IDriverLogic, DriverLogic>();
services.AddTransient<ITransportLogic, TransportLogic>();
services.AddTransient<IRouteLogic, RouteLogic>();
services.AddTransient<IStopLogic, StopLogic>();
services.AddTransient<IScheduleLogic, ScheduleLogic>();
// IoC-êîíòåéíåð, ôîðìû
services.AddTransient<FormMain>();
services.AddTransient<FormSchedule>();
services.AddTransient<FormDriver>();
services.AddTransient<FormDrivers>();
services.AddTransient<FormTransport>();
services.AddTransient<FormTransports>();
services.AddTransient<FormRoute>();
services.AddTransient<FormRoutes>();
services.AddTransient<FormRouteStop>();
services.AddTransient<FormStop>();
services.AddTransient<FormStops>();
} }
} }
} }

View File

@ -9,9 +9,29 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Remove="nlog.config" />
</ItemGroup>
<ItemGroup>
<Content Include="nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.13">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" /> <PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\RouteGuideBusinessLogics\RouteGuideBusinessLogics.csproj" />
<ProjectReference Include="..\RouteGuideContracts\RouteGuideContracts.csproj" />
<ProjectReference Include="..\RouteGuideDatabaseImplement\RouteGuideDatabaseImplement.csproj" />
</ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true" internalLogLevel="Info">
<targets>
<target xsi:type="File" name="tofile" fileName="log-${shortdate}.log" />
</targets>
<rules>
<logger name="*" minLevel="Debug" writeTo="tofile" />
</rules>
</nlog>
</configuration>