Completed
Last Updated: 12 Jun 2024 09:59 by ADMIN
Release 2024.2.612 (Preview)
Maura Regan
Created on: 04 Apr 2024 15:04
Category: UI for WinForms
Type: Bug Report
0
RadGridView: NullReferenceException with fast scrolling while adding and removing records from the OpenEdge ProBindingSource

 

I'm a Progress OpenEdge developer and found issue with RadGridView using it in a ABL application. I have been able to reproduce the issue outside of the OpenEdge environment, and have attached a project file.

 

To see the issue, run the app, and scroll down really quickly with scrollbar thumb to the bottom.

You will then get:

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=Telerik.WinControls.GridView
  StackTrace:
   at Telerik.WinControls.UI.ExpressionAccessor.EvaluateExpression(GridViewRowInfo row, GridViewColumn column)

                       

Call Stack when I'm in my project:

> WindowsFormsApp1_NetFramework.exe!Progress.Data.DataSource.FillCacheFromPVMSource(Progress.Data.CacheRow cacheRow, int rowIx) Line 579 C#
WindowsFormsApp1_NetFramework.exe!Progress.Data.DataSource.GetRowError(int rowIx) Line 651 C#
WindowsFormsApp1_NetFramework.exe!Progress.Data.DummyRow.Error.get() Line 1347 C#
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewRowInfo.ErrorText.get() Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridDataRowElement.UpdateInfo() Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridRowElement.Initialize(Telerik.WinControls.UI.GridViewRowInfo rowInfo) Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridRowElement.Attach(Telerik.WinControls.UI.GridViewRowInfo row, object context) Unknown
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.BaseVirtualizedContainer<Telerik.WinControls.UI.GridViewRowInfo>.UpdateElement(int position, Telerik.WinControls.UI.GridViewRowInfo data) Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.ScrollableRowsContainerElement.UpdateElement(int position, Telerik.WinControls.UI.GridViewRowInfo data) Unknown
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.BaseVirtualizedContainer<Telerik.WinControls.UI.GridViewRowInfo>.MeasureElements() Unknown
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.BaseVirtualizedContainer<Telerik.WinControls.UI.GridViewRowInfo>.MeasureOverride(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.ScrollableRowsContainerElement.MeasureOverride(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.dll!Telerik.WinControls.RadElement.MeasureCore(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.dll!Telerik.WinControls.RadElement.Measure(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.dll!Telerik.WinControls.Layouts.ContextLayoutManager.UpdateLayout() Unknown
Telerik.WinControls.dll!Telerik.WinControls.Layouts.ContextLayoutManager.UpdateLayoutCallback(Telerik.WinControls.Layouts.ILayoutManager manager) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.Delegate.DynamicInvokeImpl(object[] args) Line 123 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbackDo(System.Windows.Forms.Control.ThreadMethodEntry tme) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(object obj) Unknown
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 980 C#
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 928 C#
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 917 C#

 

                                                   

Once I relinguish control back to Telerik, I get:

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=Telerik.WinControls.GridView
  StackTrace:
   at Telerik.WinControls.UI.ExpressionAccessor.EvaluateExpression(GridViewRowInfo row, GridViewColumn column)


Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.ExpressionAccessor.EvaluateExpression(Telerik.WinControls.UI.GridViewRowInfo row, Telerik.WinControls.UI.GridViewColumn column) Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.ExpressionAccessor.this[Telerik.WinControls.UI.GridViewRowInfo].get(Telerik.WinControls.UI.GridViewRowInfo row) Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewRowInfo.this[Telerik.WinControls.UI.GridViewColumn].get(Telerik.WinControls.UI.GridViewColumn column) Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridDataCellElement.Value.get() Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridCellElement.SetContent() Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridVirtualizedCellElement.Initialize(Telerik.WinControls.UI.GridViewColumn column, Telerik.WinControls.UI.GridRowElement row) Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridVirtualizedCellElement.Attach(Telerik.WinControls.UI.GridViewColumn data, object context) Unknown
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.BaseVirtualizedContainer<Telerik.WinControls.UI.GridViewColumn>.InsertElement(int position, Telerik.WinControls.UI.IVirtualizedElement<Telerik.WinControls.UI.GridViewColumn> element, Telerik.WinControls.UI.GridViewColumn data) Unknown
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.BaseVirtualizedContainer<Telerik.WinControls.UI.GridViewColumn>.UpdateElement(int position, Telerik.WinControls.UI.GridViewColumn data) Unknown
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.BaseVirtualizedContainer<Telerik.WinControls.UI.GridViewColumn>.MeasureElements() Unknown
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.BaseVirtualizedContainer<Telerik.WinControls.UI.GridViewColumn>.MeasureOverride(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.dll!Telerik.WinControls.RadElement.MeasureCore(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.dll!Telerik.WinControls.RadElement.Measure(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridVirtualizedRowElement.MeasureElements(System.Drawing.SizeF availableSize, System.Drawing.SizeF clientSize, System.Windows.Forms.Padding borderThickness) Unknown
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.LightVisualElement.MeasureOverride(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridRowElement.MeasureOverride(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.dll!Telerik.WinControls.RadElement.MeasureCore(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.dll!Telerik.WinControls.RadElement.Measure(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.VirtualizedStackContainer<Telerik.WinControls.UI.GridViewRowInfo>.MeasureElementCore(Telerik.WinControls.RadElement element, System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.ScrollableRowsContainerElement.MeasureElementCore(Telerik.WinControls.RadElement element, System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.VirtualizedStackContainer<Telerik.WinControls.UI.GridViewRowInfo>.MeasureElement(Telerik.WinControls.UI.IVirtualizedElement<Telerik.WinControls.UI.GridViewRowInfo> element) Unknown
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.BaseVirtualizedContainer<Telerik.WinControls.UI.GridViewRowInfo>.MeasureElements() Unknown
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.BaseVirtualizedContainer<Telerik.WinControls.UI.GridViewRowInfo>.MeasureOverride(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.ScrollableRowsContainerElement.MeasureOverride(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.dll!Telerik.WinControls.RadElement.MeasureCore(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.dll!Telerik.WinControls.RadElement.Measure(System.Drawing.SizeF availableSize) Unknown
Telerik.WinControls.dll!Telerik.WinControls.Layouts.ContextLayoutManager.UpdateLayout() Unknown
Telerik.WinControls.dll!Telerik.WinControls.Layouts.ContextLayoutManager.UpdateLayoutCallback(Telerik.WinControls.Layouts.ILayoutManager manager) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.Delegate.DynamicInvokeImpl(object[] args) Line 123 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbackDo(System.Windows.Forms.Control.ThreadMethodEntry tme) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(object obj) Unknown
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 980 C#
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 928 C#
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 917 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallback(System.Windows.Forms.Control.ThreadMethodEntry tme) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbacks() Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.ScrollableControl.WndProc(ref System.Windows.Forms.Message m) Unknown
Telerik.WinControls.dll!Telerik.WinControls.RadControl.WndProc(ref System.Windows.Forms.Message m) Unknown
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.RadGridView.WndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm) Unknown
> WindowsFormsApp1_NetFramework.exe!WindowsFormsApp1_NetFramework.Program.Main() Line 19 C#

 

/////////////////////////////////////////////////////////////////////////////////////////////////

The following notes will explain what we are doing, since it may not be typical.

 

The MaxDataGuess functionality offers a time-saving alternative for the OpenEdge BindingSource that binds to a query with 
a very large result set. 
Some .NET controls must know the number of records in the result set when they initialize. 
By default, the ProBindingSource counts the records by reading the records in the query's result set, which can be time-consuming for large 
result sets. Setting this property provides the .NET control with an estimated value to bypass the counting process.
Sometimes, the result list can contain tens of thousands records, so this functionality would be used for that use case.


The project that demonstrates the issue found with the Telerik GridView is a much simpler version of the actual OpenEdge implementation.
The Progress.Data.DataSource._actualNumberOfRecords property is just a hard coded value that takes the place of the ABL query result set list,
since this project does not include the OpenEdge specific code.

The internal implementation of the MaxDataGuess in this project is as follows:

The DataSource.Count property is originally set to 50.
See Form1.cs:  pbs = new Progress.Data.BindingSource(myDataTable, maxDataGuess);


Once user scrolls through rows close to the Count property,  the routine CheckForOffEnd() is called 
(triggered by IDataErrorInfo.Error property).
If it determines that we are close to "current" end of rows, it adds 100 more rows calling
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, ix));
to notify the grid control that we've update the Count property.

The routine FillCacheFromPVMSource() is called to fill in the CacheRow param for the specified rowIx.
The exception comes into play when the rowIx is greater than the current Count property.
If this is the case, then FillCacheFromPVMSource() updates the Count property, and also calls
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, ix));
when adjusting the Count property to notify the Telerik grid.

The exception occurs when control passes back to the Telerik code. 
The rowIx is no longer valid, and the Telerik grid does not check for this.


We get the following System.NullReferenceException:

'Object reference not set to an instance of an object.'

 

7 comments
ADMIN
Todor
Posted on: 03 Jun 2024 11:56

Hello,

The scenario you encountered with RadGridView is quite uncommon and we have not received other reports for a similar behavior so far. During high-speed scrolling operations, multiple events are triggered, including scrolling, adding, and deleting records. This flood of messages can occasionally cause the RadGridView control to enter an invalid state. The same is also happening with the standard Microsoft grid which also crashes in this setup.

I have thoroughly investigated the high-speed scrolling issue and can confirm that we can modify our code to prevent exceptions. However, please note that although exceptions will be avoided, the grid may still display unusual visual behavior.

We have updated the status of this item to "In Development" and adjusted your Telerik points as a token of our gratitude for bringing this issue to our attention.

Fabian, could you please share your project with us? This will help us investigate further and determine if it is related to the issue reported by Maura Regan. So far, we have been unable to replicate the error on our end.

As there is no current workaround for this bug, we have increased its priority. The item is now scheduled for fixing, and we will keep you informed of any updates to its status.

Thank you for your patience and cooperation.

Regards,
Todor
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Fabian
Posted on: 27 May 2024 12:07

Hello Dinko

 

We use RadGridView from the Telerik Version 2023.3.1010.48 and we get the same Problem. When we initialize the GridView with a table of 10 entries. When change the view to an other GridView and then go back, we don't get the failure again.

 

Maybe this information are useful.

I hope you can find this issue.

Thanks

 

Call Stack after occuring the exception:

                                              

> Progress.NetUI.dll!Progress.Data.DataSource.CheckForOffEnd(int rowIx) Line 1310 C#
Progress.NetUI.dll!Progress.Data.DataSource.GetRowError(int rowIx) Line 1643 C#
Progress.NetUI.dll!Progress.Data.DummyRow.Error.get() C#
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridViewRowInfo.ErrorText.get() Line 207 C#
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridDataRowElement.UpdateInfo() Line 59 C#
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridRowElement.Initialize(Telerik.WinControls.UI.GridViewRowInfo rowInfo) Line 307 C#
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.GridRowElement.Attach(Telerik.WinControls.UI.GridViewRowInfo row, object context) Line 677 C#
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.BaseVirtualizedContainer<Telerik.WinControls.UI.GridViewRowInfo>.InsertElement(int position, Telerik.WinControls.UI.IVirtualizedElement<Telerik.WinControls.UI.GridViewRowInfo> element, Telerik.WinControls.UI.GridViewRowInfo data) Line 146 C#
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.BaseVirtualizedContainer<Telerik.WinControls.UI.GridViewRowInfo>.UpdateElement(int position, Telerik.WinControls.UI.GridViewRowInfo data) Line 199 C#
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.ScrollableRowsContainerElement.UpdateElement(int position, Telerik.WinControls.UI.GridViewRowInfo data) Line 139 C#
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.BaseVirtualizedContainer<Telerik.WinControls.UI.GridViewRowInfo>.MeasureElements() Line 88 C#
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.BaseVirtualizedContainer<Telerik.WinControls.UI.GridViewRowInfo>.MeasureOverride(System.Drawing.SizeF availableSize) Line 75 C#
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.ScrollableRowsContainerElement.MeasureOverride(System.Drawing.SizeF availableSize) Line 41 C#
Telerik.WinControls.dll!Telerik.WinControls.RadElement.MeasureCore(System.Drawing.SizeF availableSize) Line 3203 C#
Telerik.WinControls.dll!Telerik.WinControls.RadElement.Measure(System.Drawing.SizeF availableSize) Line 2801 C#
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.RowsContainerElement.MeasureOverride(System.Drawing.SizeF availableSize) Line 235 C#
Telerik.WinControls.dll!Telerik.WinControls.RadElement.MeasureCore(System.Drawing.SizeF availableSize) Line 3203 C#
Telerik.WinControls.dll!Telerik.WinControls.RadElement.Measure(System.Drawing.SizeF availableSize) Line 2801 C#
Telerik.WinControls.dll!Telerik.WinControls.Layouts.ContextLayoutManager.UpdateLayout() Line 651 C#
Telerik.WinControls.dll!Telerik.WinControls.Layouts.ContextLayoutManager.UpdateLayoutCallback(Telerik.WinControls.Layouts.ILayoutManager manager) Line 461 C#
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.Delegate.DynamicInvokeImpl(object[] args) Line 102 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbackDo(System.Windows.Forms.Control.ThreadMethodEntry tme) Line 10021 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(object obj) Line 9983 C#
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 503 C#
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 475 C#
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 468 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallback(System.Windows.Forms.Control.ThreadMethodEntry tme) Line 9970 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbacks() Line 10049 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) Line 14818 C#
System.Windows.Forms.dll!System.Windows.Forms.ScrollableControl.WndProc(ref System.Windows.Forms.Message m) Line 1369 C#
Telerik.WinControls.dll!Telerik.WinControls.RadControl.WndProc(ref System.Windows.Forms.Message m) Line 1416 C#
Telerik.WinControls.GridView.dll!Telerik.WinControls.UI.RadGridView.WndProc(ref System.Windows.Forms.Message m) Line 3257 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) Line 135 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) Line 163 C#
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) Line 640 C#
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData) Line 337 C#
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context) Line 1232 C#
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) Line 1148 C#
System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm) Line 3009 C#
[Native to Managed Transition]
[Managed to Native Transition]
Progress.NetUI.dll!Progress.ClrBridge.ClrApi.InvokeMethod(string typeName, string methodName, System.Type[] types, object[] args) Line 457 C#
Progress.clrbridge.dll!<Module>.Progress.ClrBridge.BrgClrFromPro.invokeMethod(Progress.ClrBridge.BrgClrFromPro* value, sbyte* A_0, sbyte* A_1, int A_2, prmhdr* A_3) Line 1872 C#

 

 

ADMIN
Dinko | Tech Support Engineer
Posted on: 10 May 2024 10:41

Hi Maura Regan,

I appreciate the additional details. We will need more time to investigate this and take into consideration your last post. I will contact you again as soon as we have more information. 

Regards,
Dinko | Tech Support Engineer
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Maura Regan
Posted on: 08 May 2024 15:10

The routine CheckForOffEnd() in the simple reproducible, as well as the real app, does not, and cannot know if we are at the real end of the records. It just knows that we are at the 'manufactured/current' end of records, If it detects we are at this current end of records, its adds  BindingSource.MAXDATAGUESS_INCR   (100) rows to its _count property, and calls

OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, ix));

so the bound control knows there are more records.

 

In the real app, FillCacheFromPVMSource() calls to the OpenEdge  backend datasource to get more records. This is the routine that can detect the true end of records.  Once it determines this, it sets:

 _pbs._bAccurateCount = true;

 

so that CheckForOffEnd() know that we have hit the true end of records, and it will stop adding new rows.

 

In the simple reproducible, in FillCacheFromPVMSource(), I added the uaage of _actualNumberOfRecords since we are not using an OpenEdge  backend datasource. This is the only routine that should access the _actualNumberOfRecords  property.

 

 

Maura Regan
Posted on: 07 May 2024 20:10

 

This is not a correct fix for problem. I need the Exception resolved.

In the real app's code base, the property that corresponds to the this._actualNumberofRecords property is not known until the OpenEdge backend Query has been scrolled thru to the last record in the query result list. I used a hardcoded count for the ultimate max number of records to give you a realistic reproducible of the issue.  It would be too complex to give you the actual ABL OpenEdge application.

We need the Exception resolved.

Sorry for any confusion.

ADMIN
Dinko | Tech Support Engineer
Posted on: 22 Apr 2024 14:19

Hello Maura,

Thank you for being so patient.

After investigating the project and the DataSource class, the exception comes from calling the OnListChanged event too many times. This is not directly related to our RadGridView control. The event is called more times than the actual items in the row. When slowly scrolling the rows, the RadGridView validates the added rows and manages to handle this scenario. However, when you scroll very fast, the control cannot validate on time the rows that are added and the number of ListChanged event calls and throws an exception for an item that does not exist in the source. 

To handle this scenario, you will need to add an additional check in the CheckForOffEnd() method. 

internal void CheckForOffEnd(int rowIx)
{
   . . . . . .// your code
    if (rowIx == _count - 1 && _newIx == -1)
    {
       . . . . . .// your code
	   
        if (_pbs.Batching == true)
        {
           . . . . . .// your code

            if (rowsAdded > 0)
            {
                // We'll add the actual rows (DummyRow objects)
                // when the control asks for them.
                //_count += rowsAdded;
                totalCnt = _count + rowsAdded;
				
                if (totalCnt > this._actualNumberOfRecords)
                {
                    totalCnt = this._actualNumberOfRecords;
                }
				
                // Let the bound controls know of the change
                // OE00164955: Change from ItemAdded for each new row to Reset.
                // When combining batching/sorting, and sending these individually, they don't
                // get to grid in order we send them. Changing to Reset fixes problem.
                // OE00165534 Called Reset wasn't correct. It caused this regression.
                // Problem wasn't ItemAdded. It was the fact that _count was being set up front before
                // all calls to OnListChanged() were made. Incrementing _count as each call is done fixes both problems.
                //OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1, -1));
                for (int ix = oldCnt; ix < totalCnt; ix++)
                {
                    _count++;
                    OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, ix));
                }
            }
        }
        // _bAccurateCount can only be set when _maxDataGuess is set and we haven't hit OffEnd
        else if (_pbs._bAccurateCount == false)
        {
            int totalCnt = _count + BindingSource.MAXDATAGUESS_INCR;

            if (totalCnt > this._actualNumberOfRecords)
            {
                totalCnt = this._actualNumberOfRecords;
            }

            for (int ix = oldCnt; ix < totalCnt; ix++)
            {
                _count++;
                OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, ix));
            }
        }
    }
    _inCheckForOffEnd = false;
}

I have added the check in both places. You could double-check if you need to add somewhere else in the custom class.

Regards,
Dinko | Tech Support Engineer
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

ADMIN
Dinko | Tech Support Engineer
Posted on: 11 Apr 2024 11:02

Hi Maura Regan,

Thank you for the provided project and details. We were able to reproduce the exception in the project. However, we will need more time to investigate this exception and why the row is detached from its template. We will contact you again here as soon as we have more information. 

Regards,
Dinko | Tech Support Engineer
Progress Telerik

A brand new ThemeBuilder course was just added to the Virtual Classroom. The training course was designed to help you get started with ThemeBuilder for styling Telerik and Kendo UI components for your applications. You can check it out at https://learn.telerik.com