【问题标题】:C# - Editing Listbox ItemsC# - 编辑列表框项
【发布时间】:2017-05-24 15:43:06
【问题描述】:

我正在 Windows 窗体中制作一个模拟销售点的应用程序。我现在正在创建用户单击产品按钮的部分,它会在列表框中添加这样的项目:“'数量' - '产品名称' - '成本'”。

当再次单击按钮时,应该像这样编辑项目:“'数量+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 是我从数据库中得到的值(产品的成本)。

我的目标是,当第二次点击等时,在不创建新项目的情况下增加数量并增加成本。 我可以删除该项目并使用新信息添加另一个项目,但我希望该项目与另一个项目位于同一位置,而不是在列表的末尾。

感谢任何建议和帮助。 希望你们明白我的意图。

【问题讨论】:

  • 这是 ASP.NET WebForms 还是 WindowsForms?
  • @Guilherme WindowsForms
  • SQL 注入警告。您可能需要在此处考虑参数化。
  • 您要替换什么项目?选择一个,最后一个?
  • @RossBush 你这是什么意思?你能澄清一下吗?

标签: c# winforms listbox listboxitems


【解决方案1】:

这一行:

  listvenda.Items.Add(text1);            

这就是为什么您每次都会看到一个新项目。成熟的应用程序更有可能使用private classModel 方法。

在同一个命名空间中创建一个新的类文件并命名它。见下文:

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;

这是未经测试的,因为我目前正在从事另一个项目,但应该作为概念证明。

【讨论】:

  • 据说名为“name”的变量是让我用我的button.Text代替?我在“公共覆盖 ToString()”上有一个错误。它说:“返回类型必须是 'string' 以匹配被覆盖的成员 'object.ToString()'”。你能告诉我如何解决这个错误吗?我在“.ToString(c, CultureInfo.CurrentCulture)”中有错误,因为它既不识别“c”也不识别“CultureInfo”?如果你能帮助我,我将不胜感激。
  • 那是因为我打错了。我没有在覆盖中包含输入。固定。
【解决方案2】:

这只是为了学习,我不建议在测试环境之外使用它,但你可以这样做:

插入

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 solution

【讨论】:

  • 这不适合我的项目,因为我打算用几个按钮来做这件事,都在同一个列表框中。不过还是谢谢! :)
  • @MiniKing17-Tiago 以及与此代码有什么关系的几个按钮?我知道bprod1 是一个按钮,但如果您有多个按钮,您可以使用sender 为所有按钮创建单个功能,或者在下一个功能等中将名称更改为bprod2。在CDove asnwer 中也是如此。跨度>
  • 哦,好吧,忘了,我正在以另一种方式阅读代码。你是对的。
猜你喜欢
  • 2021-12-15
  • 2015-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多