0

我想通过按另一种形式的按钮从一种形式的datagridview中删除一条记录。但我收到一个nullreferenceexception was unhandled错误。我是 c# 的新手,所以如果有人能给我写正确的代码,我将不胜感激。

这是我到目前为止所得到的。

private void button1_Click(object sender, EventArgs e)
{
    SqlConnection con = new SqlConnection(@" Data Source=HOME-D2CADC8D4F\SQL;Initial Catalog=motociclete;Integrated Security=True");

    SqlCommand cmd = new SqlCommand();
    for (int i = 0; i < dataGridView1.Rows.Count; i++)
    {
        DataGridViewRow dr = dataGridView1.Rows[i];
        if (dr.Selected == true)
        {
            dataGridView1.Rows.RemoveAt(i);
            try
            {
                con.Open();
                cmd.CommandText = "Delete from motociclete where codm=" + i + "";
                cmd.ExecuteNonQuery();
                con.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }
    this.Close();
}
4

5 回答 5

1

只需反转循环的诗句。

 for (int i = dataGridView1.Rows.Count - 1; i >= 0 ; i--)

通过这种方式,您的循环不受行数变化的影响

还。在这种情况下,我不会在每次命令执行时打开/关闭连接,如果以这种方式使用参数,命令执行可能会更高效

using(SqlConnection con = new SqlConnection(@" Data Source=HOME-D2CADC8D4F\SQL;Initial Catalog=motociclete;Integrated Security=True"))
using(SqlCommand cmd = new SqlCommand("Delete from motociclete where codm=@id", con))
{
    con.Open();
    cmd.Parameters.AddWithValue("@id", 0);
    for (int i = dataGridView1.Rows.Count-1; i >= 0; i++)
    {
        DataGridViewRow dr = dataGridView1.Rows[i];
        if (dr.Selected == true)
        {
            dataGridView1.Rows.RemoveAt(i);
            cmd.Parameters["@id"].Value = i;
            cmd.ExecuteNonQuery();
        }
    }
}
于 2013-05-18T19:45:05.673 回答
0
private void button1_Click(object sender, EventArgs e)
{  int row =-1;   

      SqlConnection con = new SqlConnection(@" Data Source=HOME-D2CADC8D4F\SQL;Initial Catalog=motociclete;Integrated Security=True");

    SqlCommand cmd = new SqlCommand();
    row = new_tab_Object.CurrentCell.RowIndex;

            if (row!= (-1))
            {

                new_tab_Object.Rows.RemoveAt(row);                
                row = -1;
            try
            {
                con.Open();
                cmd.CommandText = "Delete from motociclete where codm=" + row + "";
                cmd.ExecuteNonQuery();
                con.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

    this.Close();
  }

你这个...

于 2013-05-18T20:16:03.023 回答
0

您在迭代它们时删除了行,这导致NullPointerException因为当您删除行时,计数正在发生变化,但循环仍然会持续与初始计数一样长。

一种方法是创建临时行列表并在之后删除它们:

List<DataGridViewRow> rowstodelete = new List<DataGridViewRow>();

for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
    DataGridViewRow dr = dataGridView1.Rows[i];
    if (dr.Selected)
    {
        rowstodelete.Add(dr);
        try
        {
              con.Open();
              cmd.CommandText = "Delete from motociclete where codm=" + i + "";
              cmd.ExecuteNonQuery();
              con.Close();
         }
         catch (Exception ex)
         {
               MessageBox.Show(ex.ToString());
         }
    }
}

foreach (DataGridViewRow row in rowstodelete)
{
    dataGridView1.Rows.Remove(row);
}
于 2013-05-18T19:38:25.293 回答
0

我看到您正在尝试从另一种形式访问一种形式的网格。确保您正确获取表单的引用(带有网格的那个)并使用它来引用网格。要实现这一点,您可能必须将您的网格对象公开。

在您的父表单中公开网格的属性

public GridView Grid
{
    return dataGridView1;
}

..当您启动新表单(例如 ChildForm)时,请这样做

Form child = new ChildForm(this);
child.Show();

请更改您的子表单以使用构造函数参数。

private Form m_ParentForm;
public ChildForm(Form child)
{
   m_ParentForm = child;
}

..你的循环看起来像这样

for (int i = 0; i < m_ParentForm.Grid.Rows.Count; i++)

希望这可以帮助。

于 2013-05-18T21:29:29.577 回答
0

为什么要遍历所有行,使用dataGridView1.SelectedRows:

for (int i = dataGridView1.SelectedRows.Count - 1; i >= 0; i--)
    dataGridView1.Rows.Remove(dataGridView1.SelectedRows[i]);

还可以使用 DataTable 和 BindingSource 绑定数据。

于 2013-05-18T20:46:41.590 回答