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



我正在使用GridViews和数据库中的数据来构建书店。有复选框,每行都有一个数量文本框。我正在验证以确保检查至少一个复选框,并且在击中提交之前,选定的行具有数量输入。当用户命中提交时,应将所选数据填充到另一个GridView中。

我遇到的问题是,当我选择两本不同的书并击中提交时,在Gridview上填充的书籍只是两次重复一本书。

*当我提交时,lblerror文本仍在显示false的可见性。

这是提交按钮调用的片段:

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");
    }
}

您需要从此

更改代码
Book objBook = new Book();
foreach (GridViewRow row in gvBooks.Rows)
{
    ....

到这个

foreach (GridViewRow row in gvBooks.Rows)
{
    Book objBook = new 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");
    }
}

最新更新