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

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

问题描述

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

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

未选中CheckBox时,该行应消失。为了立即运行,我在 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();
            }
        }
    }
}

编辑

有什么办法使它与空格键一起工作吗? .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中引发异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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