在我的 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?
修改 该异常在运行时中的任何位置抛出,而不是由AcceptChanges()直接抛出
Edit The exception is thrown anywhere in the 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
发布评论