Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataGrid throws IndexOutOfRangeException from CurrencyManager when any cell clicked

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    
like image 255
Don Vince Avatar asked Jan 18 '23 11:01

Don Vince


2 Answers

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.

like image 110
Mohammed Avatar answered Jan 30 '23 21:01

Mohammed


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..
    }
}
like image 32
Damith Avatar answered Jan 30 '23 21:01

Damith