IndexOutOfBoundsException when data is updated

I'm having issues with my datagridviews. I have my application listening to events and updating its data tables based on them. I'm not providing any user interactivity and I have no use for any selection, but I have no idea how to turn that off. The reason is - as these things are being updated, I'm having the views die off, because (at least this seems to be how it's going down) the datagridview is trying to select a row that was just deleted as it was updated. It's giving error boxes at runtime saying row X doesn't exist when it's being selected. Is there some way I can prevent them from ever trying to make that selection? If not, how can I at least go about preventing that from killing off my datagridviews?
[726 byte] By [Doogshnooglis] at [2007-12-22]
# 1
Post some code
KenTucker at 2007-8-30 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...
# 2
There's not really code worth posting. I don't do any handling of any of the UI events - just data parsing into my data tables the views are sourced from. What is it you're hoping to find out? Even that might get me thinking in the right direction for a solution.
Doogshnooglis at 2007-8-30 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...
# 3

Okay, I grabbed something potentially useful. It's the stack trace that came up in the pop-up when the error happened at runtime.

************** Exception Text **************

System.NullReferenceException: Object reference not set to an instance of an object.

at System.Windows.Forms.DataGridViewCell.GetEditedFormattedValue(Object value, Int32 rowIndex, DataGridViewCellStyle& dataGridViewCellStyle, DataGridViewDataErrorContexts context)

at System.Windows.Forms.DataGridViewCell.PaintWork(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)

at System.Windows.Forms.DataGridViewRow.PaintCells(Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, Int32 rowIndex, DataGridViewElementStates rowState, Boolean isFirstDisplayedRow, Boolean isLastVisibleRow, DataGridViewPaintParts paintParts)

at System.Windows.Forms.DataGridViewRow.Paint(Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, Int32 rowIndex, DataGridViewElementStates rowState, Boolean isFirstDisplayedRow, Boolean isLastVisibleRow)

at System.Windows.Forms.DataGridView.PaintRows(Graphics g, Rectangle boundingRect, Rectangle clipRect, Boolean singleHorizontalBorderAdded)

at System.Windows.Forms.DataGridView.PaintGrid(Graphics g, Rectangle gridBounds, Rectangle clipRect, Boolean singleVerticalBorderAdded, Boolean singleHorizontalBorderAdded)

at System.Windows.Forms.DataGridView.OnPaint(PaintEventArgs e)

at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)

at System.Windows.Forms.Control.WmPaint(Message& m)

at System.Windows.Forms.Control.WndProc(Message& m)

at System.Windows.Forms.DataGridView.WndProc(Message& m)

at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)

at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)

at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

So it looks like my code was never touched here. I need to either figure out a way to actually catch that error and just move on, or prevent it from occurring in the first place. I'm not sure, but I get the impression it's a synchronization thing within DataGridView that's exposed by the high speed I'm changing the data at.

Doogshnooglis at 2007-8-30 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...
# 4

lol u better post the code bra.

hrubesh at 2007-8-30 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...
# 5
Look, I don't mean to be argumentative, but I don't see the point in my posting two thousand lines of code in this application when the only interaction I have with the problematic object is a series of calls to AcceptChanges() on its data source. I'm not saying there's no value in sample code. But if somebody's going to be able to help with my problem here, it's not going to be because of something they saw in my code. It's going to be because they know how these UI elements behave, and what could cause them to throw exceptions when trying to redraw.
Doogshnooglis at 2007-8-30 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...
# 6

System.NullReferenceException: Object reference

it is quite obvious that one object is not yet initialised and used.

System.Windows.Forms.DataGridViewCell.GetEditedFormattedValue(Object value, Int32 rowIndex, DataGridViewCellStyle& dataGridViewCellStyle, DataGridViewDataErrorContexts context

referencing your datagrid at some moment.. thats all i can deduce.

I'm having the views die off, because (at least this seems to be how it's going down) the datagridview is trying to select a row that was just deleted as it was updated

http://www.microsoft.com/mspress/books/sampchap/5199b.asp

Resolving Update Conflicts

......setting the DataAdapter's ContinueUpdateOnErrors property to True.......

maybe this can help alrite amigos.

hrubesh at 2007-8-30 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...
# 7

How do you bind your datagridviews?

vkh75 at 2007-8-30 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...
# 8

hrubesh: These are DataGridView objects, not SQL DataAdapter objects. That would definitely be a useful-sounding thing to have, but it doesn't exist for these.

vkh75: I set the DataSource with _dataGridView1.DataSource = new DataView(_myData.Table);

When updates come in, I use _myData.Select("phrase") to get an array of rows, and set the values in those rows, or use the SetColumNameNull() method to set values null for them. In the background, I have a worker thread running, calling _myData.AcceptChanges() every second. But, evidently, the GUI isn't waiting for that method to be called to update itself. I'll get a burst of, say, eight hundred events, and the GUI'll update eight hundred times, and once in a while, when that happens, I get that paint error and one of my DataGridView elements dies off. It doesn't take the application down. I just end up with a red x where I'm supposed to have a list of data. I tried setting the RowStateFilter property, but that doesn't seem to be applicable. I basically want the GUI to wait until I call AcceptChanges to actually redraw itself. I may have to just buffer differently, but I don't tihnk I should have to.

Doogshnooglis at 2007-8-30 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...
# 9
Doogshnooglis wrote:

hrubesh: These are DataGridView objects, not SQL DataAdapter objects. That would definitely be a useful-sounding thing to have, but it doesn't exist for these.

truly: i got no idea of what's the difference for the time being.

hrubesh at 2007-8-30 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...
# 10

In case this is of any use to anybody - I *partially* solved the issue with some strategies I found. Apparently there are some synchronization issues internal to these objects, and they're exposed by high-speed updating like I'm doing. I put BeginLoadData and EndLoadData calls around my LoadDataRow calls, and it lowered the occurrence of errors. I'm still winding up with dying data grid views, but not nearly as frequently. I'm going to try putting those calls around my updates to existing rows too, and see if that helps anything. I'm also getting row paint errors, and I think they have the same kind of cause, but not exactly the same. So that's the next hurdle - figuring out why it is that these are getting paint errors and fixing it, and handling the "Index 0 does not have a value" IORE that I'm hearing about in the dataerror event.

Doogshnooglis at 2007-8-30 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...
# 11

Just another update (it's good to have posts like this.. They come up in frustrated people's web searches)...

I wrapped updates to existing rows in calls to dataName.tableName.BeginInit() and dataName.tableName.EndInit() and it made a dent in the errors. They're still occurring on occasion, but not anywhere near as often. The last change I've made, though I haven't gotten to do any significant testing for longevity with it in place yet, is to set error.Cancel to true in the DataError event's handler. I was already doing error.ThrowException = false, but that didn't seem to have any effect.

Anybody able to throw any warnings my way on what setting Cancel to true may do? I mean - does it roll back the change to the data source, or just cancel the graphical update until next time, etc?

On a related note - is there, like, a row paint error event or something? Most of these problems would be solved if I could just handle that event by having it ignore the error and/or retry. It seems like fifty percent of the grid losses I've been having are because of those errors, and the rest have been the data errors.

Doogshnooglis at 2007-8-30 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...