diff --git a/AccordionBus/AccordionBus/BusCollectionForm.Designer.cs b/AccordionBus/AccordionBus/BusCollectionForm.Designer.cs index 00731c4..ae76ada 100644 --- a/AccordionBus/AccordionBus/BusCollectionForm.Designer.cs +++ b/AccordionBus/AccordionBus/BusCollectionForm.Designer.cs @@ -30,6 +30,8 @@ { pictureBoxCollection = new PictureBox(); panelTools = new Panel(); + buttonSortByColor = new Button(); + buttonSortByType = new Button(); buttonDeleteObject = new Button(); listBoxStorages = new ListBox(); maskedTextBoxStorageName = new MaskedTextBox(); @@ -60,6 +62,8 @@ // // panelTools // + panelTools.Controls.Add(buttonSortByColor); + panelTools.Controls.Add(buttonSortByType); panelTools.Controls.Add(buttonDeleteObject); panelTools.Controls.Add(listBoxStorages); panelTools.Controls.Add(maskedTextBoxStorageName); @@ -74,11 +78,32 @@ panelTools.Size = new Size(174, 461); panelTools.TabIndex = 1; // + // buttonSortByColor + // + buttonSortByColor.Font = new Font("Segoe UI", 8F, FontStyle.Regular, GraphicsUnit.Point); + buttonSortByColor.Location = new Point(22, 237); + buttonSortByColor.Name = "buttonSortByColor"; + buttonSortByColor.Size = new Size(130, 30); + buttonSortByColor.TabIndex = 10; + buttonSortByColor.Text = "Сортировка по цвету"; + buttonSortByColor.UseVisualStyleBackColor = true; + buttonSortByColor.Click += buttonSortByColor_Click; + // + // buttonSortByType + // + buttonSortByType.Location = new Point(22, 201); + buttonSortByType.Name = "buttonSortByType"; + buttonSortByType.Size = new Size(130, 30); + buttonSortByType.TabIndex = 9; + buttonSortByType.Text = "Сортировка по типу"; + buttonSortByType.UseVisualStyleBackColor = true; + buttonSortByType.Click += buttonSortByType_Click; + // // buttonDeleteObject // - buttonDeleteObject.Location = new Point(30, 180); + buttonDeleteObject.Location = new Point(22, 165); buttonDeleteObject.Name = "buttonDeleteObject"; - buttonDeleteObject.Size = new Size(120, 40); + buttonDeleteObject.Size = new Size(130, 30); buttonDeleteObject.TabIndex = 8; buttonDeleteObject.Text = "Удалить набор"; buttonDeleteObject.UseVisualStyleBackColor = true; @@ -88,24 +113,24 @@ // listBoxStorages.FormattingEnabled = true; listBoxStorages.ItemHeight = 15; - listBoxStorages.Location = new Point(30, 110); + listBoxStorages.Location = new Point(22, 95); listBoxStorages.Name = "listBoxStorages"; - listBoxStorages.Size = new Size(120, 64); + listBoxStorages.Size = new Size(130, 64); listBoxStorages.TabIndex = 7; listBoxStorages.SelectedIndexChanged += listBoxStorages_SelectedIndexChanged; // // maskedTextBoxStorageName // - maskedTextBoxStorageName.Location = new Point(30, 30); + maskedTextBoxStorageName.Location = new Point(22, 30); maskedTextBoxStorageName.Name = "maskedTextBoxStorageName"; - maskedTextBoxStorageName.Size = new Size(120, 23); + maskedTextBoxStorageName.Size = new Size(130, 23); maskedTextBoxStorageName.TabIndex = 6; // // buttonAddObject // - buttonAddObject.Location = new Point(30, 60); + buttonAddObject.Location = new Point(22, 59); buttonAddObject.Name = "buttonAddObject"; - buttonAddObject.Size = new Size(120, 40); + buttonAddObject.Size = new Size(130, 30); buttonAddObject.TabIndex = 5; buttonAddObject.Text = "Добавить набор"; buttonAddObject.UseVisualStyleBackColor = true; @@ -113,16 +138,16 @@ // // maskedTextBoxNumber // - maskedTextBoxNumber.Location = new Point(30, 300); + maskedTextBoxNumber.Location = new Point(22, 322); maskedTextBoxNumber.Name = "maskedTextBoxNumber"; - maskedTextBoxNumber.Size = new Size(120, 23); + maskedTextBoxNumber.Size = new Size(130, 23); maskedTextBoxNumber.TabIndex = 4; // // buttonRefreshCollection // - buttonRefreshCollection.Location = new Point(30, 400); + buttonRefreshCollection.Location = new Point(22, 400); buttonRefreshCollection.Name = "buttonRefreshCollection"; - buttonRefreshCollection.Size = new Size(120, 40); + buttonRefreshCollection.Size = new Size(130, 40); buttonRefreshCollection.TabIndex = 3; buttonRefreshCollection.Text = "Обновить коллекцию"; buttonRefreshCollection.UseVisualStyleBackColor = true; @@ -130,9 +155,9 @@ // // buttonRemoveBus // - buttonRemoveBus.Location = new Point(30, 330); + buttonRemoveBus.Location = new Point(22, 351); buttonRemoveBus.Name = "buttonRemoveBus"; - buttonRemoveBus.Size = new Size(120, 40); + buttonRemoveBus.Size = new Size(130, 30); buttonRemoveBus.TabIndex = 2; buttonRemoveBus.Text = "Удалить автобус"; buttonRemoveBus.UseVisualStyleBackColor = true; @@ -140,9 +165,9 @@ // // buttonAddBus // - buttonAddBus.Location = new Point(30, 250); + buttonAddBus.Location = new Point(22, 286); buttonAddBus.Name = "buttonAddBus"; - buttonAddBus.Size = new Size(120, 40); + buttonAddBus.Size = new Size(130, 30); buttonAddBus.TabIndex = 1; buttonAddBus.Text = "Добавить автобус"; buttonAddBus.UseVisualStyleBackColor = true; @@ -163,7 +188,7 @@ menuStrip.Items.AddRange(new ToolStripItem[] { файлToolStripMenuItem }); menuStrip.Location = new Point(0, 0); menuStrip.Name = "menuStrip"; - menuStrip.Size = new Size(176, 24); + menuStrip.Size = new Size(56, 24); menuStrip.TabIndex = 2; menuStrip.Text = "menuStrip"; // @@ -177,14 +202,14 @@ // saveToolStripMenuItem // saveToolStripMenuItem.Name = "saveToolStripMenuItem"; - saveToolStripMenuItem.Size = new Size(180, 22); + saveToolStripMenuItem.Size = new Size(141, 22); saveToolStripMenuItem.Text = "Сохранение"; saveToolStripMenuItem.Click += saveToolStripMenuItem_Click; // // LoadToolStripMenuItem // LoadToolStripMenuItem.Name = "LoadToolStripMenuItem"; - LoadToolStripMenuItem.Size = new Size(180, 22); + LoadToolStripMenuItem.Size = new Size(141, 22); LoadToolStripMenuItem.Text = "Загрузка"; LoadToolStripMenuItem.Click += LoadToolStripMenuItem_Click; // @@ -236,5 +261,7 @@ private ToolStripMenuItem LoadToolStripMenuItem; private OpenFileDialog openFileDialog; private SaveFileDialog saveFileDialog; + private Button buttonSortByType; + private Button buttonSortByColor; } } \ No newline at end of file diff --git a/AccordionBus/AccordionBus/BusCollectionForm.cs b/AccordionBus/AccordionBus/BusCollectionForm.cs index f773a3d..377838c 100644 --- a/AccordionBus/AccordionBus/BusCollectionForm.cs +++ b/AccordionBus/AccordionBus/BusCollectionForm.cs @@ -51,7 +51,7 @@ namespace AccordionBus listBoxStorages.Items.Clear(); for (int i = 0; i < _storage.Keys.Count; i++) { - listBoxStorages.Items.Add(_storage.Keys[i]); + listBoxStorages.Items.Add(_storage.Keys[i].Name); } if (listBoxStorages.Items.Count > 0 && (index == -1 || index >= listBoxStorages.Items.Count)) @@ -64,6 +64,27 @@ namespace AccordionBus } } + /// + /// Сортировка по сравнителю + /// + /// + private void CompareBuses(IComparer comparer) + { + if (listBoxStorages.SelectedIndex == -1) + { + return; + } + + var obj = _storage[listBoxStorages.SelectedIndex.ToString() ?? string.Empty]; + if (obj == null) + { + return; + } + + obj.Sort(comparer); + pictureBoxCollection.Image = obj.ShowBuses(); + } + /// /// Добавление набора в коллекцию /// @@ -71,7 +92,7 @@ namespace AccordionBus /// private void buttonAddObject_Click(object sender, EventArgs e) { - if (string.IsNullOrEmpty(buttonAddObject.Text)) + if (string.IsNullOrEmpty(maskedTextBoxStorageName.Text)) { MessageBox.Show("Не все данные заполнены", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); _logger.LogWarning($"Не удалось добавить набор: {maskedTextBoxStorageName.Text}. Не все данные заполнены"); @@ -153,7 +174,7 @@ namespace AccordionBus _logger.LogWarning($"Не удалось добавить объект: {ex.Message}"); MessageBox.Show($"Не удалось добавить объект: {ex.Message}"); } - + }); form.Show(); } @@ -194,7 +215,7 @@ namespace AccordionBus _logger.LogInformation($"Удален объект с позиции {pos}"); } } - catch(Exception ex) + catch (Exception ex) { _logger.LogWarning($"Не удалось удалить объект: {ex.Message}"); MessageBox.Show($"Не удалось удалить объект: {ex.Message}"); @@ -268,5 +289,19 @@ namespace AccordionBus } } } + + /// + /// Сортировка по типу + /// + /// + /// + private void buttonSortByType_Click(object sender, EventArgs e) => CompareBuses(new BusCompareByType()); + + /// + /// Сортировка по цвету + /// + /// + /// + private void buttonSortByColor_Click(object sender, EventArgs e) => CompareBuses(new BusCompareByColor()); } } diff --git a/AccordionBus/AccordionBus/BusCollectionInfo.cs b/AccordionBus/AccordionBus/BusCollectionInfo.cs new file mode 100644 index 0000000..a385db7 --- /dev/null +++ b/AccordionBus/AccordionBus/BusCollectionInfo.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AccordionBus.Generics +{ + /// + /// Класс для хранения описания коллекции + /// + public class BusCollectionInfo : IEquatable + { + /// + /// Название коллекции + /// + public string Name { get; private set; } + + /// + /// Описание коллекции + /// + public string Description { get; private set; } + + /// + /// Конструктор + /// + /// Название коллекции + /// Описание коллекции + public BusCollectionInfo(string name, string description) + { + Name = name; + Description = description; + } + + /// + /// Сравнение названий + /// + /// Название + /// + public bool Equals(BusCollectionInfo? other) + { + return Name == other?.Name; + } + + /// + /// Получение хэш-кода + /// + /// + public override int GetHashCode() + { + return Name.GetHashCode(); + } + } +} diff --git a/AccordionBus/AccordionBus/BusCompareByColor.cs b/AccordionBus/AccordionBus/BusCompareByColor.cs new file mode 100644 index 0000000..3cd1bbd --- /dev/null +++ b/AccordionBus/AccordionBus/BusCompareByColor.cs @@ -0,0 +1,62 @@ +using AccordionBus.Drawings; +using AccordionBus.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AccordionBus +{ + /// + /// Класс реализации сравнения объектов по цвету + /// + public class BusCompareByColor : IComparer + { + /// + /// Сравнение объектов + /// + /// Первый объект + /// Второй объект + /// + /// + public int Compare(DrawingBus? x, DrawingBus? y) + { + // Проверка на null + if (x == null || x.EntityBus == null) + { + throw new ArgumentNullException(nameof(x)); + } + if (y == null || y.EntityBus == null) + { + throw new ArgumentNullException(nameof(y)); + } + + // Проверка по основному цвету + var bodyColorCompare = x.EntityBus.BodyColor.Name.CompareTo(y.EntityBus.BodyColor.Name); + if (bodyColorCompare != 0) + { + return bodyColorCompare; + } + + // Проверка по дополнительному цвету + if (x.EntityBus is EntityAccordionBus objX && y.EntityBus is EntityAccordionBus objY) + { + var additionalColorCompare = objX.AdditionalColor.Name.CompareTo(objY.AdditionalColor.Name); + if (additionalColorCompare != 0) + { + return additionalColorCompare; + } + } + + // Проверка по остальным параметрам + var speedCompare = x.EntityBus.Speed.CompareTo(y.EntityBus.Speed); + if (speedCompare != 0) + { + return speedCompare; + } + + return x.EntityBus.Weight.CompareTo(y.EntityBus.Weight); + } + } +} diff --git a/AccordionBus/AccordionBus/BusCompareByType.cs b/AccordionBus/AccordionBus/BusCompareByType.cs new file mode 100644 index 0000000..d3d2e03 --- /dev/null +++ b/AccordionBus/AccordionBus/BusCompareByType.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AccordionBus.Drawings; + +namespace AccordionBus.Generics +{ + /// + /// Класс реализации сравнения объектов по типу + /// + public class BusCompareByType : IComparer + { + /// + /// Сравнение объектов + /// + /// Первый объект + /// Второй объект + /// + /// + public int Compare(DrawingBus? x, DrawingBus? y) + { + // Проверка на null + if (x == null || x.EntityBus == null) + { + throw new ArgumentNullException(nameof(x)); + } + if (y == null || y.EntityBus == null) + { + throw new ArgumentNullException(nameof(y)); + } + + // Проверка по типу + if (x.GetType().Name != y.GetType().Name) + { + return x.GetType().Name.CompareTo(y.GetType().Name); + } + + // Проверка по остальным параметрам + var speedCompare = x.EntityBus.Speed.CompareTo(y.EntityBus.Speed); + if (speedCompare != 0) + { + return speedCompare; + } + + return x.EntityBus.Weight.CompareTo(y.EntityBus.Weight); + } + } +} diff --git a/AccordionBus/AccordionBus/BusGenericCollection.cs b/AccordionBus/AccordionBus/BusGenericCollection.cs index d6102a4..a49009b 100644 --- a/AccordionBus/AccordionBus/BusGenericCollection.cs +++ b/AccordionBus/AccordionBus/BusGenericCollection.cs @@ -47,6 +47,12 @@ namespace AccordionBus.Generics /// public IEnumerable GetBuses => _collection.GetBuses(); + /// + /// Сортировка + /// + /// + public void Sort(IComparer comparer) => _collection.SortSet(comparer); + /// /// Конструктор /// @@ -75,7 +81,7 @@ namespace AccordionBus.Generics throw new NullReferenceException(); } - return collect?._collection.Insert(obj) ?? -1; + return collect?._collection.Insert(obj, new DrawingBusEqutables()) ?? -1; } /// diff --git a/AccordionBus/AccordionBus/BusGenericStorage.cs b/AccordionBus/AccordionBus/BusGenericStorage.cs index c4612ca..57a3a75 100644 --- a/AccordionBus/AccordionBus/BusGenericStorage.cs +++ b/AccordionBus/AccordionBus/BusGenericStorage.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Xml.Linq; namespace AccordionBus { @@ -17,12 +18,12 @@ namespace AccordionBus /// /// Словарь (хранилище) /// - readonly Dictionary> _busStorages; + readonly Dictionary> _busStorages; /// /// Возвращение списка названий наборов /// - public List Keys => _busStorages.Keys.ToList(); + public List Keys => _busStorages.Keys.ToList(); /// /// Ширина окна отрисовки @@ -56,7 +57,7 @@ namespace AccordionBus /// Высота картинки public BusGenericStorage(int pictureWidth, int pictureHeight) { - _busStorages = new Dictionary>(); + _busStorages = new Dictionary>(); _pictureWidth = pictureWidth; _pictureHeight = pictureHeight; } @@ -67,7 +68,15 @@ namespace AccordionBus /// Название набора public void AddSet(string name) { - _busStorages.Add(name, new BusGenericCollection(_pictureWidth, _pictureHeight)); + BusCollectionInfo info = new BusCollectionInfo(name, string.Empty); + + // Проверка наличия ключа + if (_busStorages.ContainsKey(info)) + { + return; + } + + _busStorages.Add(info, new BusGenericCollection(_pictureWidth, _pictureHeight)); } /// @@ -76,13 +85,15 @@ namespace AccordionBus /// Название набора public void DelSet(string name) { + BusCollectionInfo info = new BusCollectionInfo(name, string.Empty); + // Проверка наличия ключа - if (!_busStorages.ContainsKey(name)) + if (!_busStorages.ContainsKey(info)) { return; } - _busStorages.Remove(name); + _busStorages.Remove(info); } /// @@ -94,10 +105,12 @@ namespace AccordionBus { get { + BusCollectionInfo info = new BusCollectionInfo(ind, string.Empty); + // Проверка наличия ключа - if (_busStorages.ContainsKey(ind)) + if (_busStorages.ContainsKey(info)) { - return _busStorages[ind]; + return _busStorages[info]; } return null; @@ -117,7 +130,7 @@ namespace AccordionBus } StringBuilder data = new(); - foreach (KeyValuePair> record in _busStorages) + foreach (KeyValuePair> record in _busStorages) { StringBuilder records = new(); foreach (DrawingBus? elem in record.Value.GetBuses) @@ -190,7 +203,8 @@ namespace AccordionBus } } } - _busStorages.Add(record[0], collection); + + _busStorages.Add(new BusCollectionInfo(record[0], string.Empty), collection); line = reader.ReadLine(); } } diff --git a/AccordionBus/AccordionBus/DrawingBusEqutables.cs b/AccordionBus/AccordionBus/DrawingBusEqutables.cs new file mode 100644 index 0000000..9c01362 --- /dev/null +++ b/AccordionBus/AccordionBus/DrawingBusEqutables.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AccordionBus.Drawings; +using AccordionBus.Entities; + +namespace AccordionBus.Generics +{ + /// + /// Класс для реализации сравнения объектов + /// + internal class DrawingBusEqutables : IEqualityComparer + { + /// + /// Сравнение объектов + /// + /// Первый объект + /// Второй объект + /// + /// + public bool Equals(DrawingBus? x, DrawingBus? y) + { + // Проверки на null + if (x == null || x.EntityBus == null) + { + throw new ArgumentNullException(nameof(x)); + } + if (y == null || y.EntityBus == null) + { + throw new ArgumentNullException(nameof(y)); + } + + // Сравнение типов объектов + if (x.GetType().Name != y.GetType().Name) + { + return false; + } + + // Сравнение параметров базовых объектов + if (x.EntityBus.Speed != y.EntityBus.Speed) + { + return false; + } + if (x.EntityBus.Weight != y.EntityBus.Weight) + { + return false; + } + if (x.EntityBus.BodyColor != y.EntityBus.BodyColor) + { + return false; + } + + // Сравнение параметров продвинутых объектов + if (x is DrawingAccordionBus && y is DrawingAccordionBus) + { + EntityAccordionBus objX = (EntityAccordionBus)x.EntityBus; + EntityAccordionBus objY = (EntityAccordionBus)y.EntityBus; + + if (objX.AdditionalColor != objY.AdditionalColor) + { + return false; + } + if (objX.AdditionalBody != objY.AdditionalBody) + { + return false; + } + if (objX.AdditionalDoor != objY.AdditionalDoor) + { + return false; + } + } + + return true; + } + + /// + /// Получение хэш-кода объекта + /// + /// + /// + public int GetHashCode([DisallowNull] DrawingBus obj) + { + return obj.GetHashCode(); + } + } +} diff --git a/AccordionBus/AccordionBus/SetGeneric.cs b/AccordionBus/AccordionBus/SetGeneric.cs index 09da159..c3d2d06 100644 --- a/AccordionBus/AccordionBus/SetGeneric.cs +++ b/AccordionBus/AccordionBus/SetGeneric.cs @@ -43,9 +43,9 @@ namespace AccordionBus.Generics /// /// Добавляемый автобус /// - public int Insert(T bus) + public int Insert(T bus, IEqualityComparer? equal = null) { - return Insert(bus, 0); + return Insert(bus, 0, equal); } /// @@ -54,7 +54,7 @@ namespace AccordionBus.Generics /// Добавляемый автобус /// Позиция /// - public int Insert(T bus, int position) + public int Insert(T bus, int position, IEqualityComparer? equal = null) { if (_places.Count >= _maxCount) { @@ -67,6 +67,11 @@ namespace AccordionBus.Generics return -1; } + if (equal != null && _places.Contains(bus, equal)) + { + throw new ArgumentException("Данный объект уже есть в коллекции"); + } + // Вставка по позиции _places.Insert(position, bus); return position; @@ -95,6 +100,12 @@ namespace AccordionBus.Generics return true; } + /// + /// Сортировка набора объектов + /// + /// + public void SortSet(IComparer comparer) => _places.Sort(comparer); + /// /// Получение объекта из набора по позиции /// diff --git a/data.txt b/data.txt new file mode 100644 index 0000000..c4cfa1f --- /dev/null +++ b/data.txt @@ -0,0 +1,2 @@ +BusStorage +0|100:100:Blue;100:100:Green;100:100:Red;100:100:Magenta:Red:True:True;100:100:Black:Green:True:True;100:100:Gray:Blue:True:True;100:100:White:Yellow:True:True;100:100:Yellow:White:True:True;100:100:Blue:Gray:True:True;100:100:Green:Black:True:True;100:100:Red:Magenta:True:True;100:100:Magenta:Black:True:False;100:100:Black:Black:True:False;100:100:Gray:Black:True:False;100:100:White:Black:True:False;100:100:Yellow:Black:True:False;100:100:Blue:Black:True:False;100:100:Green:Black:True:False;100:100:Red:Black:True:False;100:100:Magenta;100:100:Black;100:100:Gray;100:100:White;100:100:Yellow;100:100:Blue;100:100:Green;100:100:Red;