C# — Редактирование элементов списка

Я делаю приложение в Windows Forms, которое имитирует точку продаж. Сейчас я создаю часть, где пользователь нажимает кнопку продукта, и он добавляет в список элемент, подобный этому: «Количество» — «Название продукта» — «Стоимость».

При повторном нажатии кнопки предполагается редактирование товара следующим образом: "'Количество+1' - 'Наименование товара' - 'Стоимость*2'". Однако он просто добавляет еще один элемент с этой информацией.

Пока мой код выглядит следующим образом:

private void bprod1_Click(object sender, EventArgs e)
    {            
        MySqlCommand cmdp1 = new MySqlCommand("SELECT preco_unitario FROM produtos where designacao='" + bprod1.Text + "';", mConn);
        mConn.Open();
        MySqlDataReader drp1 = cmdp1.ExecuteReader();
        drp1.Read();
        string getpreco1 = drp1["preco_unitario"].ToString();
        mConn.Close();
        quant1 = quant1 + 1;
        var preco1tot = quant1 * Convert.ToDecimal(getpreco1);
        var text1 = quant1.ToString() + " - " + bprod1.Text + " - " + preco1tot.ToString();
        listvenda.Items.Add(text1);            
    }

bprod1 — моя кнопка. quant1 начинается со значения 0. getpreco1 — это значение, которое я получаю из базы данных (стоимость продукта).

Моя цель состоит в том, чтобы при втором нажатии и т. д. увеличить количество и добавить стоимость, не создавая новый элемент. Я мог бы просто удалить элемент и добавить еще один с новой информацией, но я хочу, чтобы элемент был в том же месте, что и другой, а не в конце списка.

Я ценю любые предложения и помощь. Надеюсь, вы понимаете, что я собираюсь сделать.


person MiniKing17 - Tiago    schedule 24.05.2017    source источник
comment
Это ASP.NET WebForms или WindowsForms?   -  person Guilherme    schedule 24.05.2017
comment
@Гильерме WindowsForms   -  person MiniKing17 - Tiago    schedule 24.05.2017
comment
Предупреждение об инъекции SQL. Возможно, вы захотите рассмотреть параметризацию здесь.   -  person Ross Bush    schedule 24.05.2017
comment
Какой элемент вы хотите заменить? Выбран один, последний?   -  person Logman    schedule 24.05.2017
comment
@RossBush Что ты имеешь в виду? Не могли бы вы пояснить меня, пожалуйста?   -  person MiniKing17 - Tiago    schedule 24.05.2017
comment
@Logman Я хочу заменить элемент информацией о продукте. То есть предмет может быть первым, а может быть и четвертым или пятым, у него нет правильного положения.   -  person MiniKing17 - Tiago    schedule 24.05.2017
comment
@ MiniKing17-Tiago, откуда ты знаешь, какой предмет нужно заменить?   -  person Logman    schedule 24.05.2017
comment
@Logman В этом проблема, я не знаю, как это сделать, возможно, если он ищет название продукта в элементах и ​​выбирает элемент, содержащий это имя.   -  person MiniKing17 - Tiago    schedule 24.05.2017
comment
@ MiniKing17-Tiago. Как будет выглядеть ваш запрос и что произойдет, если кто-то введет '; drop table produtos -- в ваше текстовое поле?   -  person Chris Dunaway    schedule 24.05.2017
comment
@ChrisDunaway Какое текстовое поле? У меня нет текстового поля в этой части кода. bprod1.Text — это кнопка. У меня есть .Text, потому что я хочу знать текст, который появляется на кнопке.   -  person MiniKing17 - Tiago    schedule 24.05.2017


Ответы (2)


Эта строка:

  listvenda.Items.Add(text1);            

Вот почему вы видите новый элемент каждый раз. Зрелое приложение с большей вероятностью будет использовать подходы private class или Model.

Создайте новый файл класса в том же пространстве имен и назовите его как-нибудь. Смотри ниже:

public class myProduct
{
    public int Quantity {get; set;}
    public int Name     {get; set;}
    public double Price {get; set;}

    public myProduct(string name)
    { 
      this.Quantity = 1; this.Name = name; this.Price = 0;
    }
    public override string ToString()
    {
      return this.Quantity.ToString() + "-" + this.Name + "-" + 
             (this.Price * this.Quantity).ToString(c, 
             CultureInfo.CurrentCulture);
    }
}

Теперь, когда вы просто добавляли значения, вы можете проверить, существует ли строка, и, если она существует, поработать с ней. В противном случае добавьте новую строку. Не беспокойтесь о методах ToString() и тому подобном, так как вы можете заполнить свой список списком нового класса! Он будет вызывать метод ToString() при отображении значений.

List<myProduct> listvendaBind = new List<myProduct>();

///insert code here to build your list from the database if you havent already.  Otherwise, skip this step so you dont overwrite your list

//now the code for modification
var x = listvendaBind.Where(t => t.Name == newProduct.Name).FirstOrDefault();

  if(x.Count() > 0 && (x != null)
         listvendaBind[listvendaBind.IndexOf(x[0])].Quantity++;
  else
         listvendaBind.Add(newProduct);

  listvenda.DataSource = listvendaBind;

Это не проверено, так как я сейчас работаю над другим проектом, но должно служить доказательством концепции.

person CDove    schedule 24.05.2017
comment
Предположительно, переменная с именем name предназначена для замены моей кнопкой. Текст? И у меня есть ошибка при публичном переопределении ToString(). В нем говорится: тип возвращаемого значения должен быть «строка», чтобы соответствовать переопределенному члену «object.ToString()». Можете ли вы сказать мне, как исправить эту ошибку? У меня ошибка в .ToString(c, CultureInfo.CurrentCulture), так как он не распознает ни c, ни CultureInfo? Если бы вы могли мне помочь, я был бы признателен. - person MiniKing17 - Tiago; 24.05.2017
comment
Это потому, что я опечатался. Я не включил ввод в переопределение. Исправлена. - person CDove; 24.05.2017

Это только для обучения, и я не рекомендую использовать его вне среды тестирования, но вы можете сделать что-то вроде этого:

вставка из

listvenda.Items.Add(text1);

сделай это:

bool notFound = true;
for(int i=0; i<listvenda.Items.Count; i++)
{ 
    if(((string)listvenda.Items[i]).Contains(" - " + bprod1.Text + " - "))
    {
        listvenda.Items[i] = text1;
        notFound = false;
        break;
    }
}

if(notFound)
    listvenda.Items.Add(text1);

но, как я уже сказал, это должно быть только временное решение. Вместо этого используйте решение CDove

person Logman    schedule 24.05.2017
comment
Это не подходит для моего проекта, потому что я планирую сделать это с помощью нескольких кнопок в одном списке. Но все равно спасибо! :) - person MiniKing17 - Tiago; 24.05.2017
comment
@ MiniKing17-Tiago, а какое отношение к этому коду имеют несколько кнопок? Я понимаю, что bprod1 — это кнопка, но если у вас их больше одной, вы можете использовать sender для создания одной функции для всех кнопок или просто изменить имя на bprod2 в следующей функции и т. д. То же самое и в ответе CDove. - person Logman; 24.05.2017
comment
О, хорошо, забудьте, я читал код по-другому. Ты прав. - person MiniKing17 - Tiago; 24.05.2017