Почему мой gridview заполняет неверные данные в моих строках? - PullRequest
0 голосов
/ 22 февраля 2019

Я строю книжный магазин, используя GridViews и данные из моей базы данных.Есть флажки, и у каждой строки есть текстовое поле количества.Я проверяю, чтобы убедиться, что по крайней мере один флажок установлен и что выбранная строка имеет ввод количества перед нажатием подтвержденияКогда пользователь нажимает «Отправить», выбранные данные должны быть введены в другое представление сетки.

Проблема, с которой я столкнулся, заключается в том, что когда я выбираю две разные книги и нажимаю «Отправить», книги, заполненные в сетке, просто повторяют только одну книгу дважды.

* Также текст 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");
    }
}

1 Ответ

0 голосов
/ 22 февраля 2019

Вам нужно изменить код с этого

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

на этот

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

Причина проста.Если вы создаете экземпляр Book вне цикла и внутри цикла вы устанавливаете его свойства и добавляете его в список, во втором цикле вы изменяете свойства одного и того же экземпляра на другие значения и добавляете ссылку во второй раз всписок.В конце цикла в вашем списке будет много ссылок на один и тот же экземпляр, а его свойствам будут заданы последние значения, прочитанные внутри цикла.

Если вы объявляете и инициализируете экземпляр 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");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...