I have a data grid on a windows form.
When I initially update that grid to contain data, and then click on it, I get the below exception.
Notably the exception is deep down in the windows handling of the form, and so the exception is caught at the point whereby I launch the form.
Please note, I had to tick "Show External Code" in the Call Stack to show the Call Stack below, otherwise it just shows [External Code].
In terms of hunches/troubleshooting steps, thinking that it may have been caused by a message that is fired for the item which was selected and then the item which is now selected, I have tried to .SelectAll();
on the DataGridView
after updating the data, this had the same results.
The Exception:
IndexOutOfRangeException
{"Index -1 does not have a value."}
The Call Stack:
System.Windows.Forms.dll!System.Windows.Forms.CurrencyManager.this[int].get(int index) + 0xa1 bytes
System.Windows.Forms.dll!System.Windows.Forms.CurrencyManager.Current.get() + 0x16 bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.DataGridViewDataConnection.OnRowEnter(System.Windows.Forms.DataGridViewCellEventArgs e) + 0x101 bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.OnRowEnter(ref System.Windows.Forms.DataGridViewCell dataGridViewCell = null, int columnIndex = 1, int rowIndex = 0, bool canCreateNewRow, bool validationFailureOccurred) + 0x218 bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.SetCurrentCellAddressCore(int columnIndex = 1, int rowIndex = 0, bool setAnchorCellAddress, bool validateCurrentCell, bool throughMouseClick = true) + 0x59f bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.OnCellMouseDown(System.Windows.Forms.DataGridView.HitTestInfo hti, bool isShiftDown, bool isControlDown) + 0x12db bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.OnCellMouseDown(System.Windows.Forms.DataGridViewCellMouseEventArgs e) + 0x318 bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.OnMouseDown(System.Windows.Forms.MouseEventArgs e) + 0x153 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseDown(ref System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button, int clicks) + 0xcf bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x86e bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.WndProc(ref System.Windows.Forms.Message m) + 0x92 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0x10 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x31 bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 513, System.IntPtr wparam, System.IntPtr lparam) + 0x57 bytes
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason = 4, int pvLoopData = 0) + 0x24e bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = 4, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.Application.ModalApplicationContext}) + 0x177 bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x61 bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.RunDialog(System.Windows.Forms.Form form) + 0x33 bytes
System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window owner) + 0x373 bytes
The issue was finally resolved by using a generic BindingList
as a data source rather than a generic List
.
As the values in the datasource needed to be changed in reaction to user interaction with the form, we were repopulating the list and reattaching it every time it changed (when it was a List<>
).
After implementing INotifyPropertyChanged
on the object in the list, we used BindingList<>
and now bind the data once and refresh when needed.
While I still dont know why using the list was causing issues, I am happy that I have a workable solution.
if you handling click events in code behind do proper validation before perform any task.
if (e.ColumnIndex == 1) // check for correct column
{
if (e.RowIndex >= 0) // check for valied row index
{
DataGridViewRow dataGridViewRow = dataGridView1.Rows[e.RowIndex];
// do stuff like update delete..
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With