为什么我的gridview会填充行中的错误数据?

时间:2019-02-22 19:30:53

标签: c# asp.net validation checkbox

我正在使用GridViews和数据库中的数据来建立书店。有复选框,每行都有一个数量文本框。我正在确认确保至少一个复选框已选中,并且选中的行在点击提交之前具有数量输入。当用户单击“提交”时,应将所选数据填充到另一个gridview中。

我遇到的问题是,当我选择两本不同的书并单击提交时,gridview中填充的书仅重复一本书两次。

*当我在提交时将可见性设置为false时,lblError文本仍然显示。

以下是“提交”按钮调用的摘要:

protected void btnSubmit_Click(object sender, EventArgs e)
{
    double saleCount = 0;

    Processor p = new Processor();
    Book objBook = new Book();

    foreach (GridViewRow row in gvBooks.Rows)
    {
        CheckBox chkbx = (CheckBox)row.Cells[0].FindControl("cbBook");
        string title = row.Cells[1].Text;
        string authors = row.Cells[2].Text;
        string isbn = row.Cells[3].Text;
        DropDownList gvType = (DropDownList)row.Cells[4].FindControl("ddBookType");
        DropDownList gvMethod = (DropDownList)row.Cells[5].FindControl("ddMethod");
        TextBox qty = (TextBox)row.Cells[6].FindControl("txtQty");

        String strType = Convert.ToString(gvType.Text);
        String strMethod = Convert.ToString(gvMethod.Text);

        if (chkbx.Checked && !(string.IsNullOrEmpty(qty.Text)))
        {
            panelHeader.Visible = false;
            panelStudentInfo.Visible = false;
            panelCampus.Visible = false;
            panelCatalog.Visible = false;
            panelStudentInfo2.Visible = true;
            panelCampus2.Visible = true;
            panelCatalog2.Visible = true;
            gvBooks.Visible = false;
            gvOrder.Visible = true;
            panelButtons.Visible = false;

            txtStudentID2.Text = txtStudentID.Text;
            txtStudentName2.Text = txtStudentName.Text;
            txtStudentAddr2.Text = txtStudentAddr.Text;
            txtPhoneNo2.Text = txtPhoneNo.Text;
            ddCampus2.Text = ddCampuses.Text;

            lblError.Visible = false;

            int quantity = Convert.ToInt32(qty.Text);
            objBook.Title = title;
            objBook.Authors = authors;
            objBook.ISBN = isbn;
            objBook.BookType = strType;
            objBook.Method = strMethod;
            objBook.Quantity = quantity;

            objBook.Price = p.Calculate(isbn, strType, strMethod);
            objBook.TotalCost = objBook.Price * objBook.Quantity;
            orderList.Add(objBook);

            saleCount += objBook.Quantity;

            orderTotal = objBook.TotalCost + orderTotal;

            p.UpdateDB(isbn, quantity, strMethod, objBook.TotalCost);
        }
        else
        {
            lblError.Text = "* Please select a book & enter a quantity";
            lblError.Visible = true;
        }

        gvOrder.DataSource = orderList;
        gvOrder.DataBind();

        gvOrder.Columns[0].FooterText = "Totals";
        gvOrder.Columns[5].FooterText = saleCount.ToString();
        gvOrder.Columns[6].FooterText = orderTotal.ToString("C2");
    }
}

1 个答案:

答案 0 :(得分:2)

您需要从此更改代码

Book objBook = new Book();
foreach (GridViewRow row in gvBooks.Rows)
{
    ....

对此

foreach (GridViewRow row in gvBooks.Rows)
{
    Book objBook = new Book();
    .....

原因很简单。如果在循环外创建Book实例,然后在循环内设置它的属性并将其添加到列表中,则在第二个循环中,将同一实例的属性更改为不同的值,并再次将引用添加到名单。在循环结束时,您的列表将具有对SAME实例的许多引用,并且该单个实例的属性将设置为循环内读取的最后一个值。

如果在循环中声明和初始化Book实例,则在每个循环中,都有一个Book实例要添加到列表中,并且每个实例都有自己的属性值。

为了更好地查看您的代码,我认为if检查之后的所有代码甚至都应该在数据源的设置之外进行循环。
这里是简化的代码布局,以突出显示相关点。

protected void btnSubmit_Click(object sender, EventArgs e)
{
    double saleCount = 0;

    Processor p = new Processor();

    // Prepare a list of errors 
    List<string> errors = new List<strig>();

    foreach (GridViewRow row in gvBooks.Rows)
    {
        Book objBook = new Book();
        ....    
        if (chkbx.Checked)
        {

           // Probably it is better to check here also the quantity value
           // not just for text in the textbox (it could be anything)

           if(Int32.TryParse(qty.Text, out int quantity) && quantity > 0)
           {
                // We have at least one checkbox checked with a quantity, so no error!
               .....
           }
           else
           {
              // We don't have a quantity, add book title to error list....
              errors.Add($"Book {title} has no quantity!");
           }
        }
    }

    // Handle the errors, if any
    if(errors.Count > 0)
    {
        lblError.Text = string.Join("<br/>, errors);
        lblError.Visible = true;
    }
    else
    {
        lblError.Visible = false;
        gvOrder.DataSource = orderList;
        gvOrder.DataBind();

        gvOrder.Columns[0].FooterText = "Totals";
        gvOrder.Columns[5].FooterText = saleCount.ToString();
        gvOrder.Columns[6].FooterText = orderTotal.ToString("C2");
    }
}