简体   繁体   中英

c# Insert,Delete, and Edit in Same form load datagridview

I have a datagridview with 4 columns. 1 of which is a manually added deletecheckbox column (The first column). There's some strange behavior when I try and delete multiple rows based on the checked value. For example, if I check 2 rows, 1 gets deleted. If I check 5 rows, 3 gets deleted. So basically half of what I click gets deleted. The ones don't get deleted are remained checked, and I would have to click the update button again to remove more. If I want to delete ALL checked checkboxes with one button click, what do I need to fix?

Entire Button Click Event:

private void button1_Click(object sender, EventArgs e)
    {
        SqlCommand cmdAdd = new SqlCommand("insert into Josh_REL_Table (UserID, RoleName) Values (@UserID,@RoleName)", con);
        SqlCommand cmdEdit = new SqlCommand("update Josh_Rel_Table SET UserID = @UserId, RoleName=@RoleName where RelationID=@RelationID", con);
        con.Open();


        cmdAdd.Parameters.Add("@UserID", SqlDbType.VarChar);
        cmdAdd.Parameters.Add("@RoleName", SqlDbType.VarChar);
        cmdAdd.Parameters.Add("@RelationID", SqlDbType.VarChar);

        cmdEdit.Parameters.Add("@UserID", SqlDbType.VarChar);
        cmdEdit.Parameters.Add("@RoleName", SqlDbType.VarChar);
        cmdEdit.Parameters.Add("@RelationID", SqlDbType.VarChar);

        if (DGV1.RowCount >= 1)
        {
            for (int x = 0; x < DGV1.RowCount - 1; x++)
            {
                if (DGV1.Rows[x].Cells[1].Value.ToString() == "" || DGV1.Rows[x].Cells[1].Value == null)
                {
                    cmdAdd.Parameters["@UserID"].Value = DGV1.Rows[x].Cells[2].Value.ToString();
                    cmdAdd.Parameters["@RoleName"].Value = comboBox1.Text;
                    cmdAdd.Parameters["@RelationID"].Value = DGV1.Rows[x].Cells[1].Value.ToString();
                    cmdAdd.ExecuteNonQuery();
                }
                if (!DGV1.Rows[x].IsNewRow)
                {
                    cmdEdit.Parameters["@UserID"].Value = DGV1.Rows[x].Cells[2].Value.ToString();
                    cmdEdit.Parameters["@RoleName"].Value = comboBox1.Text;
                    cmdEdit.Parameters["@RelationID"].Value = DGV1.Rows[x].Cells[1].Value.ToString();
                    cmdEdit.ExecuteNonQuery();
                }
                if (Convert.ToBoolean(DGV1.Rows[x].Cells[0].Value))
                {
                     List<DataGridViewRow> selectedRows = (from newRow in DGV1.Rows.Cast<DataGridViewRow>() where Convert.ToBoolean(newRow.Cells["Delete"].Value) == true select newRow).ToList();
                    if (MessageBox.Show(string.Format("Do you want to delete {0} rows?", selectedRows.Count), "Confirmation", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        foreach (DataGridViewRow newRow in selectedRows)
                        {

                                using (SqlCommand cmd = new SqlCommand("DELETE FROM Josh_REL_Table WHERE RelationID = @RelationID", con))
                                {
                                    cmd.CommandType = CommandType.Text;
                                    cmd.Parameters.AddWithValue("@RelationID", newRow.Cells["RelationID"].Value);

                                    cmd.ExecuteNonQuery();

                                    DGV1.Rows.Remove(newRow);
                                }

                        }
                    }
                }

            }
        }


            MessageBox.Show("Record updated!");
            con.Close();
    }

You should delete the rows backwards, beginning with the last row working your way through to the first, because otherwise the index is wrong. Consider you want to delete the rows with index 2 and 4:

index  actual row
1      Row 1
2      Row 2 <-- If you delete this
3      Row 3
4      Row 4
5      Row 5

This basically means that after deleting the row with index 2 you will continue on the row with index 3 which is now Row 4 so you never handled what should happen to Row 3:

After deletion you land here

index  actual row
1      Row 1
2      Row 3
3      Row 4
4      Row 5

Just change your loop to:

for (int x = DGV1.RowCount - 1; x >= 0; ; x--)

The part for the expression:

Everywhere you assume you van have a cell value that you want to convert to a string but might be null needs to be escaped, otherwise you will receive an error:

// Old
cmdEdit.Parameters["@UserID"].Value = DGV1.Rows[x].Cells[2].Value.ToString();

// New
cmdEdit.Parameters["@UserID"].Value = (DGV1.Rows[x].Cells[2].Value != null) ? DGV1.Rows[x].Cells[2].Value.ToString() : "";

The part below new evaluates the expression and converts the value to string if it is not null or sets the value to "" if it is null.

Kind of like this:

variable = (Expression) ? (will be evaluated if true) : (will be evaluated if false)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM