none
Проблема с DataGridView и VirtualMode RRS feed

  • Вопрос

  • Всем привет.

    Столкнулся с такой проблемой. Имеется достаточно большой набор данных. Раньше весть этот набор выводился одним select-ом в DataGridView. Решил переделать на постраничную загрузку через VirtualMode. За основу взял пример с MSDN (how to implement VirtualMode). Переделал его немного, добавил возможность сохранения всех прочитанных страниц.

    Проблема в том, что у меня всё работает и ни разу не было проблем. Но у клиента на больших объёмах часто возникает ошибка "There is no row at position {0}". Причём эта ошибка возникает либо при прокручивании сразу на большое расстояние, либо при переходе сразу в конец таблицы (Ctrl + End, например). При этом по ряду причин загрузка страницы происходит достаточно долго. У меня всё работает конечно быстро и таких ошибок не возникает.

    Собственно в чём может быть проблема? Такое ощущение, что Grid пытается прочитать строки с каким-то несуществующим индексом. Как это происходит - не понимаю. RowCount устанавливается, но запрашивается какой-то левый индекс строки. Ниже пример stacktrace-а который удалось получить:

    System.IndexOutOfRangeException: There is no row at position 235.
       at System.Data.RBTree`1.GetNodeByIndex(Int32 userIndex)
       at System.Data.RBTree`1.get_Item(Int32 index)
       at System.Data.DataRowCollection.get_Item(Int32 index)
       at AnnulmentRequestsLibrary.Cache.Cache.IfPageCached_ThenSetElement(Int32 rowIndex, Int32 columnIndex, String& element)
       at AnnulmentRequestsLibrary.Cache.Cache.RetrieveElement(Int32 rowIndex, Int32 columnIndex)
       at AnnulmentRequestsLibrary.RequestForm.dgv_CellValueNeeded(Object sender, DataGridViewCellValueEventArgs e)
       at System.Windows.Forms.DataGridView.OnCellValueNeeded(DataGridViewCellValueEventArgs e)
       at System.Windows.Forms.DataGridView.OnCellValueNeeded(Int32 columnIndex, Int32 rowIndex)
       at System.Windows.Forms.DataGridViewCell.GetValue(Int32 rowIndex)
       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)

    При этом, насколько я помню, в данном случае запрос должен был вернуть как раз-таки 235 записей. Откуда возникает попытка прочитать строку 235 (236ю запись) не понял.

Ответы