在DataGridView上多次显示表后出现NullReferenceException

时间:2018-03-23 07:48:56

标签: c# winforms ms-access datagridview

编辑2:原来它只是第一次给出NullReferenceException。在那之后,它说我不允许更改ConnectionString属性,即使我认为我已在正确的位置关闭它。

感谢您花时间阅读本文。

我正在使用一个使用MS Access数据库的WinForms应用程序,我目前遇到了我所做的条目删除功能的问题。

所以,我有一个DataGridView在按钮点击时在3个表之间切换,我有一个函数,通过单击位于结尾处的按钮来删除当前打开的表上的行。行。

当我打开我的第一个表,并尝试删除一行时,它运行正常。但是,如果我之后打开另一个表并尝试删除一个条目,或者甚至回到我打开的第一个表,我在删除函数中得到一个NullReferenceException

以下是显示DataGridView中的一个表格的代码。

public DataTable Read()
    {
        connection.ConnectionString = connectionString;
        OpenConnection(); //connection.Open() inside an if statement
        dataTable.Clear();
        OleDbCommand readStudentCommand = new OleDbCommand("select * from Students", connection); //display the whole list of students

        OleDbDataReader reader = readStudentCommand.ExecuteReader();
        dataTable.Load(reader);
        connection.Close();
        return dataTable;        
    }

以下是删除条目的代码

    private void MainDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        connection.ConnectionString = connectionString;
        if (ConnectionState.Closed == connection.State)
        {
            connection.Open();
        }
        var senderGrid = (DataGridView)sender;
        if (e.RowIndex >= 0 && senderGrid.Columns[e.ColumnIndex] == MainDataGridView.Columns["Delete"])
        {
//this function retrieves the first column value of the deleted row, which has the ID of the entry (works with any table). 
    DeleteEntry(MainDataGridView.Rows[e.RowIndex].Cells[0].Value.ToString()); //exception thrown here (System.Windows.Forms.DataGridViewCell.Value.get returned null)
        MainDataGridView.Rows.RemoveAt(e.RowIndex);
     }

这里是DeleteEntry()

private void DeleteEntry(string deletedID)
    {
        string tableName = null;
        string idType = null;
        if (studentsDisplayed)
        {
            tableName = "Students";
            idType = "Student ID";
        }
        else if(booksDisplayed)
        {
            tableName = "Books";
            idType = "BookID";
        }
        else if(loansDisplayed)
        {
            tableName = "Loans";
            idType = "Loan ID";
        }
        string deleteCommand = String.Format("DELETE * FROM {0} WHERE [{1}] = {2}", tableName, idType, deletedID);
        OleDbCommand deleteEntryCommand = new OleDbCommand(deleteCommand, connection);
        deleteEntryCommand.ExecuteNonQuery();
        SaveData(); //this method just calls Update() in a dataAdapter of a relevant table
        connection.Close();
    }

谢谢!

编辑: 根据请求,这是切换表的代码。它只是引用第一个函数,并将返回的dataTable设置为DataSource

private void StudentButton_Click(object sender, EventArgs e) //display students
    {
        try
        {
            if (!studentsDisplayed)
            {
                MainDataGridView.DataSource = studentDAL.Read(); //studentDAL is the class that works with the Students table of my DB.
                studentsDisplayed = true; //these 3 are to avoid duplicated creation of the same table
                booksDisplayed = false;
                loansDisplayed = false;
                ComboBoxChanger(); //don't mind this, it's for an irrelevant feature
                CreateButtons(5);
            }
        }
        catch
        {
            throw;
        }
    }

1 个答案:

答案 0 :(得分:0)

好的,事实证明问题是DeleteEntry(MainDataGridView.Rows[e.RowIndex].Cells[0].Value.ToString())Cells[0]部分有问题。第一次加载表后,第0个单元格就消失了。所以,我重写了代码,以便不是在tableName中声明idTypeDeleteEntry(),而是在MainDataGridView_CellContentClick()中声明它们,然后使DeleteEntry()接受3 idTypetableName作为参数,并将MainDataGridView.Rows[e.RowIndex].Cells[0].Value.ToString()参数更改为MainDataGridView.Rows[e.RowIndex].Cells[idType].Value.ToString()。现在它工作得很好!