【问题标题】:c# Insert,Delete, and Edit in Same form load datagridviewc# 在同一个表单中插入、删除和编辑加载datagridview
【发布时间】:2015-02-26 17:30:01
【问题描述】:

我有一个 4 列的数据网格视图。其中1个是手动添加的deletecheckbox列(第一列)。当我尝试根据检查值删除多行时,会出现一些奇怪的行为。例如,如果我检查 2 行,则会删除 1 行。如果我检查 5 行,则会删除 3 行。所以基本上我点击的一半被删除了。那些没有被删除的仍然处于选中状态,我必须再次单击更新按钮才能删除更多。如果我想一键删除所有选中的复选框,我需要修复什么?

整个按钮点击事件:

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

【问题讨论】:

    标签: c# sql datagridview


    【解决方案1】:

    您应该向后删除行,从最后一行开始一直到第一行,否则索引是错误的。考虑您要删除索引为 2 和 4 的行:

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

    这基本上意味着删除索引为 2 的行后,您将继续处理索引为 3 的行,即现在的第 4 行,因此您从未处理过第 3 行应该发生的情况:

    删除后你登陆这里

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

    只需将循环更改为:

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

    表达式部分:

    您假设您的任何地方都有一个单元格值,您想将其转换为字符串,但可能为 null 需要转义,否则您将收到错误:

    // 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() : "";
    

    new 下面的部分对表达式求值,如果不为 null,则将值转换为字符串,如果为 null,则将值设置为 ""。

    有点像这样:

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

    【讨论】:

    • 谢谢。但是,当我重新运行它时,我在“ if (DGV1.Rows[x].Cells[1].Value.ToString() == "" 行收到错误“对象引用未设置为对象的实例” || DGV1.Rows[x].Cells[1].Value == null)" 即使我以另一种方式循环,数据也是一样的,为什么我会得到这个?
    • 你能把 null 的测试移到 OR 的左边吗?然后首先测试它是否为 NULL,如果它不是 NULL,则测试另一个条件(空字符串)。 Null 无法转换为字符串,因此会引发错误。试试这个: if (DGV1.Rows[x].Cells[1].Value == null || DGV1.Rows[x].Cells[1].Value.ToString() == "")"
    • 当我调试时,它现在查看 if 语句,但第一行会导致同样的错误。 ( cmdAdd.Parameters["@UserID"].Value = DGV1.Rows[x].Cells[2].Value.ToString();)
    • 发生这种情况的行可能有空字段。你能在错误发生时检查“x”的值并检查应该转换的值吗?我最好的问题是您对该单元格有一个新的无价值。这反过来意味着该值为 Null,再次无法转换为字符串。
    • 对,我的目标是仅通过填写行将行添加到 datagridview/数据库,通过替换值来编辑行,并根据复选框删除行。当表单和datagridview加载时,最后一行显示n个未选中的复选框和“userID”下的一个空单元格来填写。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    相关资源
    最近更新 更多