C# 使用空格键更改复选框时,AcceptChanges()在DataGridView中引发System.NullReferenceException

C# 使用空格键更改复选框时,AcceptChanges()在DataGridView中引发System.NullReferenceException,c#,exception,datagridview,datatable,.net-4.0,C#,Exception,Datagridview,Datatable,.net 4.0,在myDataGridView中,我使用DataView来过滤DataTable。过滤器中使用复选框值 取消选中该复选框时,该行应消失。要立即运行它,我在CurrentCellDirtyStateChanged事件中使用AcceptChanges()。(否则,该行将保持显示,直到选择另一行) 当我用鼠标取消选中复选框时,此选项起作用使用空格键引发一个NullReferenceException异常 以下是一些示例代码: (完全工作。只需要带有空白DataGridView1的Form1。使用空格键

在my
DataGridView
中,我使用DataView来过滤DataTable。过滤器中使用
复选框

取消选中该复选框时,该行应消失。要立即运行它,我在
CurrentCellDirtyStateChanged
事件中使用
AcceptChanges()
。(否则,该行将保持显示,直到选择另一行)

当我用鼠标取消选中复选框时,此选项起作用使用空格键引发一个NullReferenceException异常

以下是一些示例代码:

(完全工作。只需要带有空白DataGridView1的Form1。使用空格键更改复选框会引发异常)

有没有办法让它和空格键一起工作

编辑
异常是在.net运行时的任何位置引发的,而不是由AcceptChanges()直接引发的

据报道,一个潜在的解决方法是延迟
committedit
,直到
CellDirtyStateChanged
事件处理程序完成

public delegate void InvokeDelegate();

public void MyDelegate()
{
    dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
    table.AcceptChanges();
}

//CurrentCellDirtyStateChanged Event
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dataGridView1.IsCurrentCellDirty == true && dataGridView1.CurrentCell is DataGridViewCheckBoxCell)
    {
        BeginInvoke(new InvokeDelegate(MyDelegate));
    }
}

以这种方式使用Invoke使代码更易于阅读,因为不需要显式的委托声明

private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dataGridView1.IsCurrentCellDirty == true && dataGridView1.CurrentCell is DataGridViewCheckBoxCell)
    {
        // use BeginInvoke with (MethodInvoker) to run the code after the event is finished
        BeginInvoke((MethodInvoker)delegate
        {
            dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
            table.AcceptChanges();
        });
    }
}

工作原理与tezzos答案相同。

您能发布异常的完整堆栈跟踪吗?我很好奇到底是什么东西在堆里扔的。@AnnL。编辑帖子你可以在这里找到解决方法:@tezzo工作,谢谢!!!我会接受这个答案!回答补充:请检查我的代码;如果它与您使用的不同,请随意更正。
public delegate void InvokeDelegate();

public void MyDelegate()
{
    dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
    table.AcceptChanges();
}

//CurrentCellDirtyStateChanged Event
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dataGridView1.IsCurrentCellDirty == true && dataGridView1.CurrentCell is DataGridViewCheckBoxCell)
    {
        BeginInvoke(new InvokeDelegate(MyDelegate));
    }
}
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dataGridView1.IsCurrentCellDirty == true && dataGridView1.CurrentCell is DataGridViewCheckBoxCell)
    {
        // use BeginInvoke with (MethodInvoker) to run the code after the event is finished
        BeginInvoke((MethodInvoker)delegate
        {
            dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
            table.AcceptChanges();
        });
    }
}