Для того чтобы код отвечал требованиям, описанным в вашем задании, вам потребуется реализовать механизм, обновляющий картинку и имя предмета в зависимости от уровня и зачарования. Это можно сделать, добавив дополнительную логику в ваш класс Item и предусмотрев обработчики событий для ComboBox, который будет использоваться для изменения уровня и зачарования.

Класс Item выглядит хорошо, но он не обновляет автоматически картинку и полное имя при изменении уровня и зачарования. Давайте добавим методы UpdateImageFileName() и UpdateFullEnglishName(), которые будут вызываться каждый раз при изменении свойств. Также изменим геттеры для ImageFileName и FullEnglishName таким образом, чтобы они возвращали актуальные значения.

Модифицируем класс Item:

public class Item
{
    // Опускаю объявление свойств и конструктор для краткости…

    private string _imageFileNameBase; // Базовое имя файла изображения, без уровня и зачарования
    
    public int Level
    {
        get => _level;
        set
        {
            _level = value;
            UpdateImageFileName();
            UpdateFullEnglishName();
        }
    }
    
    public int Charms
    {
        get => _charms;
        set
        {
            _charms = value;
            UpdateImageFileName();
        }
    }

    public string ImageFileName
    {
        get => GetImageFileName();
        set => imageFileNameBase = value; // Изменяем только базовое имя
    }
    
    public string FullEnglishName { get => GetFullEnglishName(); } // Теперь только геттер
    
    private void UpdateImageFileName()
    {
        ImageFileName = “T” + Level.ToString() + "" + _imageFileNameBase + (Charms > 0 ? “@” + Charms.ToString() : “”);
    }

    private void UpdateFullEnglishName()
    {
        FullEnglishName = GetLevelPrefix() + " " + EnglishName;
    }
    
    // Остальные методы и поля…
}


Теперь у нас есть модифицированные геттеры для ImageFileName и FullEnglishName, которые возвращают значения, основанные на текущем уровне и числе чар.

Последний шаг включает создание пользовательского интерфейса с ComboBox для выбора уровня и зачарования и привязку событий изменения к методам, которые будут обновлять объект Item. Предполагается, что у вас уже есть форма с элементами управления ComboBox.

Вот код обработчика событий для ComboBox:

private void LevelComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
    // предполагается, что selectedItem - это текущий выбранный в ListView объект Item
    selecteditem.Level = Convert.ToInt32(LevelComboBox.SelectedItem);
    // обновление картинки и имени в соответствии с новым уровнем
    UpdateItemInListView(selectedItem);
}

private void CharmsComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
    // предполагается, что selectedItem - это текущий выбранный в ListView объект Item
    selectedItem.Charms = Convert.ToInt32(CharmsComboBox.SelectedItem);
    // обновление картинки и имени в соответствии с новым зачарованием
    UpdateItemInListView(selectedItem);
}

private void UpdateItemInListView(Item item)
{
    // Обновление представления элемента в ListView в соответствии с изменениями
    // пример: ListViewItem.ImageKey = item.ImageFileName;
    // пример: ListViewItem.Text = item.FullEnglishName;
    // Здесь код зависит от того, как вы реализовали ListView и его элементы
}


Пожалуйста, замените плейсхолдеры и переменные в этом коде на соответствующие элементы из вашей реальной реализации формы и ListView.
Отправь только исправленный файлы ItemsList.cs и ItemsProcessing.cs
Вот изначальный ItemsList.cs
namespace Albion_Helper
{
public class Item
{
public string EnglishName { get; set; }
public string RussianName { get; set; }
public string EnglishCategory { get; set; }
public string RussianCategory { get; set; }
public string EnglishSubcategory { get; set; }
public string RussianSubcategory { get; set; }
public int MinLevel { get; set; }
public int MinCharm { get; set; }
public int Level { get; set; }
public int Charms { get; set; }
public string Quality { get; set; }
public string ImageFileName { get; set; }

public string GetImageFileName()
{
string enchantmentSuffix = Charms > 0 ? “@” + Charms.ToString() : string.Empty;
return $“T{Level}_{ImageFileName}{enchantmentSuffix}”;
}

public Item(string englishName, string russianName,
string englishCategory, string russianCategory,
string englishSubcategory, string russianSubcategory,
int minLevel, int minCharms, int level, int charms, string quality, string imageFileName)
{
EnglishName = englishName;
RussianName = russianName;
EnglishCategory = englishCategory;
RussianCategory = russianCategory;
EnglishSubcategory = englishSubcategory;
RussianSubcategory = russianSubcategory;
MinLevel = minLevel;
MinCharm = minCharms;
Level = level;
Charms = charms;
Quality = quality;
ImageFileName = imageFileName;
}

// Методы класса Item, имитирующие некоторую локализацию и логику
public string GetLocalizedCategory()
{
// Вставьте логику для выбора локализованной категории
return EnglishCategory;
}

public string GetFullEnglishName()
{
string prefix = GetLevelPrefix();
return prefix + " " + EnglishName;
}

public string GetLevelPrefix()
{
// Вставьте логику для возвращения префикса уровня
switch (Level)
{
case 1: return “Beginner’s”;
case 2: return “Novice’s”;
case 3: return “Journeyman’s”;
case 4: return “Adept’s”;
case 5: return “Expert’s”;
case 6: return “Master’s”;
case 7: return “Grandmaster’s”;
case 8: return “Elder’s”;
default: return “”;
}
}
}

public class ItemsList
{
// Приватное поле для хранения списка предметов
public List<Item> items;
public List<Item> GetItems() => items;
// Конструктор класса ItemsList
public ItemsList()
{
items = new List<Item>();

items.Add(new Item(“Arcane Staff”, “Арканый посох”,
“Weapons”, “Оружие”,
“Magic Staffs”, “Магические посохи”,
3, // Минимальный уровень этого предмета
0, // Минимальный уровень чар этого предмета
3, // Текущий уровень предмета
0, // Уровень чар предмета
“Normal”, “MAIN_ARCANESTAFF”));
items.Add(new Item(“Mercenary Hood”, “Капюшон наемника”,
“Armor”, “Броня”,
“Leather Helmet”, “Кожаный шлем”,
1, // Минимальный уровень этого предмета
0, // Минимальный уровень чар этого предмета
1, // Текущий уровень предмета
0, // Уровень чар предмета
“Normal”, “HEAD_LEATHER_SET1”));
}
}
}
А Вот изначальный файл ItemsProcessing.cs
namespace Albion_Helper
{

public class ItemsProcessing
{

public ItemsList itemsList;
private TextBox CountTextBox;
private ComboBox LevelComboBox;
private ComboBox EnchantmentComboBox;
private Form Changing;
public ItemsProcessing(Form form)
{
itemsList = new ItemsList();
Changing = form;
CountTextBox = CreateOrGetCountTextBox();
LevelComboBox = CreateOrGetComboBox(forLevel: true);
EnchantmentComboBox = CreateOrGetComboBox(forLevel: false);

// Установка начальных значений для ComboBox’ов (можно использовать другие методы для их заполнения)
PopulateLevelCombobox(LevelComboBox, 1);
PopulateEnchantmentCombobox(EnchantmentComboBox);
}


public void HandleCountKeyPress(KeyPressEventArgs e)
{
if (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar))
{
e.Handled = true;
}
}
public List<Item> GetSortedItems()
{
List<Item> items = itemsList.GetItems();
return items.OrderBy(item => item.EnglishName).ToList();
}
public void LoadImagesToImageList(ImageList imageList, string basePath)
{

foreach (var item in itemsList.GetItems())
{
// Теперь ‘imagePath’ должен быть конечный путь к картинке.
string imagePath = Path.Combine(basePath, “BuyMenu”, “ItemsIco”, item.GetImageFileName() + “.png”);


if (File.Exists(imagePath))
{
using (var bmpTemp = new Bitmap(imagePath))
{
// Заменим item.EnglishName на ImageFileName, чтобы использовать уникальное имя файла,
// так как один и тот же товар может иметь разные уровни.
imageList.Images.Add(item.ImageFileName, new Bitmap(bmpTemp));
}
}
}
}
public void PopulateBrowseList(ListView browserList, ImageList imageList)
{
List<Item> items = GetSortedItems();
browserList.Items.Clear();

foreach (Item item in items)
{
ListViewItem listViewItem = CreateBrowserListViewItem(item);
browserList.Items.Add(listViewItem);
}
}

public ListViewItem CreateBrowserListViewItem(Item item)
{
ListViewItem listViewItem = new ListViewItem();
// Устанавливаем минимальные значения из свойств MinLevel и Charms
item.Level = item.MinLevel;
item.Charms = item.MinCharm;
listViewItem.ImageKey = item.ImageFileName;
listViewItem.SubItems.Add(item.EnglishName);
listViewItem.SubItems.Add(item.GetLocalizedCategory());
listViewItem.Tag = item;
return listViewItem;
}

public ListViewItem CreateInventoryListViewItem(Item item)
{
ListViewItem listViewItem = new ListViewItem();
listViewItem.ImageKey = item.GetImageFileName();
listViewItem.SubItems.Add(item.GetFullEnglishName());
listViewItem.SubItems.Add(“1”); // Default quantity
listViewItem.SubItems.Add(item.Level.ToString());
listViewItem.SubItems.Add(item.Charms.ToString());
listViewItem.SubItems.Add(item.GetLocalizedCategory());
listViewItem.Tag = item;
return listViewItem;
}




// Конструктор с параметром, принимающий форму

public void ShowCountTextBox(ListViewItem selectedItem, ListViewItem.ListViewSubItem subItemCount)
{
TextBox quantityTextBox = CreateOrGetCountTextBox();

// Определите сдвиг по Y, чтобы подвинуть вниз, например на 2 пикселя
int yOffset = 20;

// Получаем положение ячейки внутри ListView и применяем сдвиг
Rectangle subItemRect = subItemCount.Bounds;
Point textBoxLocation = selectedItem.ListView.PointToScreen(new Point(subItemRect.Left, subItemRect.Top + yOffset));
textBoxLocation = Changing.PointToClient(textBoxLocation);

// Устанавливаем границы TextBox
quantityTextBox.SetBounds(textBoxLocation.X, textBoxLocation.Y, subItemRect.Width, subItemRect.Height - yOffset); // Уменьшаем высоту на yOffset, чтобы сохранить размер
quantityTextBox.Text = subItemCount.Text;
quantityTextBox.Visible = true;
quantityTextBox.BringToFront();
quantityTextBox.Focus();

// Важно! Связываем TextBox с ListViewItem через Tag
quantityTextBox.Tag = selectedItem;
}
private TextBox CreateOrGetCountTextBox()
{
if (CountTextBox == null || CountTextBox.IsDisposed)
{
CountTextBox = new TextBox();
CountTextBox.KeyPress += CountTextBox_KeyPress; // Обновлено
CountTextBox.Leave += CountTextBox_Leave;
Changing.Controls.Add(CountTextBox); // Добавляем контрол на форму
}
return CountTextBox;
}
private void CountTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Return)
{
TextBox tb = (TextBox)sender;
UpdateQuantity((ListViewItem)tb.Tag, tb.Text);
tb.Visible = false; // Скрыть после Enter
e.Handled = true; // Предотвратить “beep” звук
}
else
{
HandleCountKeyPress(e);
}
}
private void UpdateQuantity(ListViewItem selectedListViewItem, string newQuantity)
{
// Вы можете обновить Tag или SubItem, который содержит количество
if (selectedListViewItem != null && selectedListViewItem.Tag is Item item)
{
// Примените изменения к вашему объекту Item или обновите SubItem
selectedListViewItem.SubItems[2].Text = newQuantity; // Предполагаем, что это колонка с количеством

}
}

private void CountTextBox_Leave(object sender, EventArgs e)
{
TextBox tb = (TextBox)sender;
UpdateQuantity((ListViewItem)tb.Tag, tb.Text); // Сохранить значение перед скрытием
tb.Visible = false; // Затем скрыть TextBox
}

public void InitializeListViewMouseHandlers(ListView InventoryList)
{
InventoryList.MouseClick += InventoryListMouseClick;
}

private void InventoryListMouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ListView listView = sender as ListView;
ListViewHitTestInfo hit = listView.HitTest(e.X, e.Y);
int quantityColumnIndex = 2; // Примерный индекс для количества
int levelColumnIndex = 3; // Примерный индекс для уровня
int enchantmentColumnIndex = 4; // Примерный индекс для качества

if (hit.SubItem != null)
{
if (hit.Item.SubItems.IndexOf(hit.SubItem) == quantityColumnIndex)
{
ShowCountTextBox(hit.Item, hit.SubItem);
}
else if (hit.Item.SubItems.IndexOf(hit.SubItem) == levelColumnIndex)
{
ShowComboBox(hit.Item, hit.SubItem, forLevel: true);
}
else if (hit.Item.SubItems.IndexOf(hit.SubItem) == enchantmentColumnIndex)
{
ShowComboBox(hit.Item, hit.SubItem, forLevel: false);
}
}
}
}
// В этом методе устанавливаем ComboBox в позицию в ListView и обрабатываем его отображение и выбор значения
private void ShowComboBox(ListViewItem selectedItem, ListViewItem.ListViewSubItem subItem, bool forLevel)
{
ComboBox comboBox = forLevel ? LevelComboBox : EnchantmentComboBox;
if (forLevel)
{
int minLevel = (selectedItem.Tag as Item)?.MinLevel ?? 1; // Используйте Минимальный уровень предмета
PopulateLevelCombobox(comboBox, minLevel);
}

else
{
// Если это не уровень, тогда мы работаем с зачарованиями.
PopulateEnchantmentCombobox(comboBox);
}

// Получаем положение ячейки внутри ListView
int yOffset = 20;
Rectangle subItemRect = subItem.Bounds;
Point comboLocation = selectedItem.ListView.PointToScreen(new Point(subItemRect.Left, subItemRect.Top + yOffset));
comboLocation = Changing.PointToClient(comboLocation);
comboBox.SetBounds(comboLocation.X, comboLocation.Y, subItemRect.Width, subItemRect.Height - yOffset);
// Устанавливаем границы ComboBox точно в положении ячейки ListViewItem
comboBox.SetBounds(comboLocation.X, comboLocation.Y, subItemRect.Width, subItemRect.Height - yOffset); // Уменьшаем высоту на yOffset, чтобы сохранить размер
comboBox.Visible = true;
comboBox.BringToFront();
comboBox.Focus();
comboBox.Tag = selectedItem; // Связываем ComboBox с выбранным ListViewItem
if (selectedItem.Tag is Item item)
{
comboBox.SelectedItem = forLevel ? item.Level.ToString() : item.Charms.ToString();
}


// Подписываемся на событие SelectedIndexChanged если оно уже не подписано
if (comboBox.Tag == null)
{
comboBox.SelectedIndexChanged += (sender, e) =>
{
ComboBox cmbBox = sender as ComboBox;
ListViewItem currentlySelectedItem = cmbBox.Tag as ListViewItem; // Используем другое имя переменной

if (currentlySelectedItem != null && currentlySelectedItem.Tag is Item currentItem)
{
string value = cmbBox.SelectedItem.ToString();
if (!string.IsNullOrEmpty(value))
{
if (forLevel)
{
UpdateItemLevel(currentlySelectedItem, int.Parse(value));
}
else
{
UpdateItemCharm(currentlySelectedItem, int.Parse(value));
}
}
cmbBox.Visible = false; // Скроем ComboBox после изменения выбранного элемента
}
};
comboBox.Leave += (sender, e) =>
{
ComboBox cb = sender as ComboBox;
if (cb.Tag is ListViewItem listViewItem && listViewItem.Tag is Item taggedItem) // Переименовали item в taggedItem
{
// Для LevelComboBox
if (forLevel)
{
cb.SelectedItem = taggedItem.Level.ToString(); // Обновили item на taggedItem
}
// Для EnchantmentComboBox
else
{
cb.SelectedItem = taggedItem.Charms.ToString(); // Обновили item на taggedItem
}

cb.Visible = false; // Скроем ComboBox после изменения выбранного элемента
}
};

comboBox.Tag = new object(); // Устанавливаем Tag во избежание повторной подписки

}
}

// Обновление уровня предмета в теге ListViewItem
private void UpdateItemLevel(ListViewItem listViewItem, int newLevel)
{
if (listViewItem.Tag is Item item)
{
item.Level = newLevel;
listViewItem.ImageKey = item.GetImageFileName();
listViewItem.SubItems[1].Text = item.GetFullEnglishName(); // Обновить SubItem с полным английским названием
listViewItem.SubItems[3].Text = newLevel.ToString(); // Обновить текст подэлемента ListView для уровня
listViewItem.ListView.Refresh(); // Обновить ListView
}
}

// Обновление привлекательности предмета в теге ListViewItem
private void UpdateItemCharm(ListViewItem listViewItem, int newCharm)
{
if (listViewItem.Tag is Item item)
{
item.Charms = newCharm;
listViewItem.ImageKey = item.GetImageFileName(); // Обновляем зачарование в объекте предмета
listViewItem.SubItems[4].Text = newCharm.ToString(); // Обновляем текст подэлемента ListView для чара
listViewItem.ListView.Refresh(); // Обновляем ListView
}
}

// Создание или получение ComboBox
private ComboBox CreateOrGetComboBox(bool forLevel)
{
ComboBox comboBox = new ComboBox
{
DropDownStyle = ComboBoxStyle.DropDownList // Установите нужный стиль
};
Changing.Controls.Add(comboBox); // Сохраняем ссылку на форму для добавления контролов
comboBox.Leave += (sender, e) => comboBox.Visible = false; // Скрыть ComboBox при потере фокуса

// Добавление элементов в ComboBox
if (forLevel)
{
PopulateLevelCombobox(comboBox, 1); // Предполагаем, что уровни начинаются с 1
}
else
{
PopulateEnchantmentCombobox(comboBox); // Заполнение колдовства
}
return comboBox;
}
public void PopulateLevelCombobox(ComboBox comboBox, int minimumLevel)
{
comboBox.Items.Clear();
for (int i = minimumLevel; i <= 8; i++)
{
comboBox.Items.Add(i.ToString());
}
comboBox.SelectedIndex = 0; // Установка выбранного элемента по умолчанию
}

// Метод для заполнения ComboBox качеством (зачарованиями)
public void PopulateEnchantmentCombobox(ComboBox comboBox)
{
comboBox.Items.Clear();
for (int i = 0; i <= 3; i++)
{
comboBox.Items.Add(i.ToString());
}
comboBox.SelectedIndex = 0; // Установка выбранного элемента по умолчанию
}

}

}