使用空格键更改CheckBox时,AcceptChanges()在DataGridView中引发System.NullReferenceException [英] AcceptChanges() throws System.NullReferenceException in DataGridView when using space bar for changing CheckBox

查看:48
本文介绍了使用空格键更改CheckBox时,AcceptChanges()在DataGridView中引发System.NullReferenceException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 DataGridView 中,我使用DataView来过滤DataTable.在过滤器中使用 CheckBox 值.

In my DataGridView I use a DataView to filter the DataTable. The CheckBox value is used in the filter.

未选中复选框时,该行应消失.为了立即运行,我在 CurrentCellDirtyStateChanged 事件中使用 AcceptChanges().(否则,该行将保持显示状态,直到选择了另一行).

When the CheckBox is unchecked, the row should disappear. To run that immediately, I use AcceptChanges() in an CurrentCellDirtyStateChanged event. (Otherwise the row stays displayed, until another row is selected).

当我用鼠标取消选中复选框时,此方法有效.使用空格键会引发 NullReferenceException 异常.

以下是一些示例代码:

(完全正常.仅需要Form1带有空白DataGridView1.使用空格键更改CheckBox会引发异常)

(Full working. Needs only Form1 with a blank DataGridView1. Changing the CheckBox with space bar throws the exception)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        DataTable table;
        DataView view; 

        public Form1()
        {
            InitializeComponent();

            Init();
        }

        // Building the table and view
        private void Init()
        {
            table = new DataTable();
            table.Columns.Add("check", typeof(bool));

            table.Rows.Add(true);
            table.Rows.Add(true);
            table.Rows.Add(true);

            view = new DataView(table);
            view.RowFilter = "check = true";

            dataGridView1.DataSource = view;
        }

        // CurrentCellDirtyStateChanged Event
        private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            if (dataGridView1.IsCurrentCellDirty == true && dataGridView1.CurrentCell is DataGridViewCheckBoxCell)
            {
                dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);

                // AcceptChanges to update the view
                // works with mouse click, throws NullReferenceException when spacebar is used
                table.AcceptChanges();
            }
        }
    }
}

有什么办法可以使其与空格键一起使用吗?

Is there any way make it working with the space bar also?

修改
该异常在.net运行时中的任何位置抛出,而不是由AcceptChanges()直接抛出

Edit
The exception is thrown anywhere in the .net runtime and not directly by AcceptChanges()

System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
     bei System.Windows.Forms.DataGridViewCheckBoxCell.NotifyMASSClient(Point position)
     bei System.Windows.Forms.DataGridViewCheckBoxCell.OnKeyUp(KeyEventArgs e, Int32 rowIndex)
     bei System.Windows.Forms.DataGridView.OnKeyUp(KeyEventArgs e)
     bei System.Windows.Forms.Control.ProcessKeyEventArgs(Message& m)
     bei System.Windows.Forms.DataGridView.ProcessKeyEventArgs(Message& m)
     bei System.Windows.Forms.Control.WmKeyChar(Message& m)
     bei System.Windows.Forms.Control.WndProc(Message& m)
     bei System.Windows.Forms.DataGridView.WndProc(Message& m)
     bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
     bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
     bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
     bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
     bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
     bei Sample.Program.Main() in C:\Projects\TFS\Sample\Sample\Program.cs:Zeile 21.

推荐答案

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

Using the Invoke this way makes for me the code easier to read, because there is no explicit delegate declaration needed.

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答案相同.

Works same like tezzos answer.

这篇关于使用空格键更改CheckBox时,AcceptChanges()在DataGridView中引发System.NullReferenceException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆