0

I have made the following WinForm in which the user provide book details and create a book record. This book record gets added to the dataGridView with the checkBox automatically selected:

Windows Form

Books Added to form

Now, when I deselect some books and click on 'Insert to database' button to insert the selected books to database, one of the deselected books always gets inserted to database along with the selected ones. And that may be any one of the deselected books.
Like here I deselect some books:

deselected Books

Now when I click the 'Insert to Database' button, the unselected books will be deleted from dataGridView and the selected one will b inserted to database:

Books inserted to database along with one unselected book

Now the books inserted to database are the selected books '123','345,'678' along with one unselected book '890'. Like this, one unselected book always get inserted to database along with the selected books.
The code which I have written is:

    public partial class CreateBookRecord : Form
        {                
            DataTable addedBooks;
            DataColumn bookId, bookName, author, noOfCopies, noOfCopiesAvailable;
            DataGridViewCheckBoxColumn check;       
            public CreateBookRecord()
            {
                InitializeComponent();                   
            }

            private void CreateBookRecord_Load(object sender, EventArgs e)
            {
                check = new DataGridViewCheckBoxColumn(); //Create a checkbox column for DataGridView                   
                addedBooks = new DataTable();
                bookId = new DataColumn("Book ID", typeof(string));
                bookName = new DataColumn("Book Name", typeof(string));
                author = new DataColumn("Author", typeof(string));
                noOfCopies = new DataColumn("No of Copies", typeof(int));
                noOfCopiesAvailable = new DataColumn("No of Copies Available", typeof(int));
                addedBooks.Columns.AddRange(new DataColumn[] { bookId, bookName, author, noOfCopies,noOfCopiesAvailable });

                dataGridViewAddedBooks.Columns.Add(check); //To make first column as checkBox column
                dataGridViewAddedBooks.DataSource = addedBooks;
                dataGridViewAddedBooks.Columns["No of Copies Available"].Width = 0;
            }

            private void buttonCreateBook_Click(object sender, EventArgs e)
            {
                    try
                    {
                        addedBooks.Rows.Add(textBoxID.Text, textBoxBookName.Text, textBoxAuthorName.Text,Convert.ToInt32(textBoxNoOfCopies.Text),Convert.ToInt32(textBoxNoOfCopies.Text));                            
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }

            private void dataGridViewAddedBooks_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
            {
                DataGridViewCheckBoxCell checkcell = (DataGridViewCheckBoxCell)dataGridViewAddedBooks.Rows[e.RowIndex].Cells[0];
                checkcell.Value = true;
            }

            private void buttonInsertBooks_Click(object sender, EventArgs e)
            {           
                foreach (DataGridViewRow row in dataGridViewAddedBooks.Rows)
                {
                    DataGridViewCheckBoxCell checkcell = (DataGridViewCheckBoxCell)row.Cells[0];
                    if (checkcell.Value == check.FalseValue)
                    {
                        dataGridViewAddedBooks.Rows.Remove(row);
                    }
                }
                SqlBulkCopy copy = new SqlBulkCopy(connection);
                copy.DestinationTableName = "Book";
                try
                {
                    connection.Open();
                    copy.WriteToServer(addedBooks);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    connection.Close();
                }        
            }

I would be very thankful if anyone could help me resolve this problem.
Thank you!

Ashish
  • 118
  • 6

1 Answers1

1

I found out the problem. It lies here in this code:

foreach (DataGridViewRow row in dataGridViewAddedBooks.Rows)
                {
                    DataGridViewCheckBoxCell checkcell = (DataGridViewCheckBoxCell)row.Cells[0];
                    if (checkcell.Value == check.FalseValue)
                    {
                        dataGridViewAddedBooks.Rows.Remove(row);
                    }
                }

When we loop through DataGridView and remove the unselected rows, it creates problem.
Suppose you inserted three rows in it and unchecked the 1st and 2nd row. Now when we loop through the first row, we find a unchecked row and it is removed from DataGridView. The DataGridView will refresh itself on row removal. Now, the second row becomes it's first row. But the 'row' counter value will now be 1(0 in beginning) and it will check the second row missing the first one(which was the second one in beginning). So it doesn't get removed from the dataGridView and gets updated to database even while it's not checked.

Solution:

DataTable insertedBooks=new DataTable(); //We will use a new table to store all the cheched records
            insertedBooks = addedBooks.Clone();
            DataGridViewCheckBoxCell checkcell;
            foreach (DataGridViewRow row in dataGridViewAddedBooks.Rows)
            {               
                checkcell = (DataGridViewCheckBoxCell)row.Cells[0];
                if (checkcell.Value.Equals(true))
                {
                    insertedBooks.Rows.Add(row.Cells[1].Value.ToString(),row.Cells[2].Value.ToString(),row.Cells[3].Value.ToString(),Convert.ToInt32(row.Cells[4].Value),Convert.ToInt32(row.Cells[5].Value)); //Add all the checked records to insertedBooks table.
                }                           
            }            
            SqlBulkCopy copy = new SqlBulkCopy(connection);
            copy.DestinationTableName = "Book";
            connection.Open();
            copy.WriteToServer(insertedBooks); //Use insertedBooks table to copy records to database table.
            addedBooks.Clear(); //Delete all data from addedBooks table, it also cleard the DataGridView.
Ashish
  • 118
  • 6