IncrementalList<T>.LoadMoreItems not fire after rebind ItemsSource with SortColumnsChangning event intercepting

Hi,

I am using Xamarin Forms SfDataGrid control (v16.1.0.26) which allow multicolumn sorting and lazy loading (LoadMoreItems) with IncrementalList as ItemsSource.
But, I have a hard time to get the LoadMoreItems async method being fire under following scenario.


  1. Bind data source to SfDataGrid.ItemsSource.
  2. Data show on SfDataGrid.
  3. Scroll all the way down, and LoadMoreItems method fire as normal.
  4. Keep scrolling until it hit the last record where IncrementalList.MaxItemsCount = data source item count.
  5. Click on the column header.
  6. Intercept SfDataGrid.SortColumnsChanging event.
  7. Cancel the sort columns changing event with e.Cancel = true
  8. Unbind the SfDataGrid.ItemsSource
  9. Set ItemsSource = null.
  10. Perform a custom data source with SQL command by SELECT... ORDER BY...
  11. Rebind the ItemsSource.
  12. Data show in screen with the new sorting order.
  13. Now scroll all the way down to the last row of the loaded SfDataGrid.Rows.
  14. Problem came in, where it stop there and LoadMoreItems no longer fire.


So, my question is... is there a way to reset the SfDataGrid VScroll so the LoadMoreItems will work as normal?


Thanks,
CT

8 Replies

CC CT CHANG April 5, 2018 11:18 PM UTC

Hi,

Below is the current workaround hacking I used, and not sure will it be the right way to do so.

I have a private method ResetScrollBars() as shown below, and I call this method after step #10 in my described scenario.


private void ResetScrollBars()
{
    var scrollViewer this.dgRecords?.Children?.FirstOrDefault(v => v is ExtScrollViewer) as ExtScrollViewer;
    var container = scrollViewer?.Content as VisualContainer;
    if (container == null)
    {
        return;
    }

    container.VScrollBar.Value = 0;
    container.HScrollBar.Value = 0;
    container.ScrollRows.UpdateScrollBar();
    container.ScrollColumns.UpdateScrollBar();
}


Regards,
CT


SK Suriya Kalidoss Syncfusion Team April 9, 2018 12:45 PM UTC

Hi Chang Chiew Thou, 
 
Thank you for using Syncfusion Products, 
 
We have checked your query and please confirm, whether you are binding a new instance to SfDataGrid.ItemsSource after setting ItemsSource as null or reusing the same initial ItemsSource binding instances? We can reproduce the reported behavior while adding same instance to SfdataGrid.ItemsSource after setting as null, because we have set only ItemsSource as null, not the binding property. But if we add the new instance to SfDataGrid.ItemsSource it is working properly. So We request you to use new instance to SfDataGrid.ItemsSource after clear the records.  
 
Wrong Approach:  
sfGrid.ItemsSource = null;  
sfGrid.ItemsSource = viewmodel.GridSource;  
  
Working Code:  
 sfGrid.ItemsSource = null;  
 sfGrid.ItemsSource = new ViewModel().GridSource;  
 
  
We have attached working sample for your reference and you can download it from the below link.  
  
 
Regards, 
Suriya K 



CC CT CHANG April 10, 2018 02:25 AM UTC

Hi Suriya,

Yes, the rebind ItemsSource was the new instance, as I disposed the previous instance of IncrementalList.

I have create a sample project which having the similar code in my production code.

I have replace the SQLite database source with a sample data access.

If you compile and load the application in Android device, and keep scrolling down till the end of the list, it will auto load the next 30 records and append to the list until the last record (ID: #99).

At this point, if you perform a column sort (any column). The SfDataGrid will unbind from the ViewModel.Profiles property follow by disposed the current instance of IncrementalList right before a new instance if IncrementalList being instantiate.

Once the new data source is rebind to the SfDataGrid.ItemsSource, and you can continue scroll down the list. You will be able to scroll all the way to the last record.

But, if you remark all the code under the ResetScrollBars() method, and repeat the above steps. You will notice the LoadMoreItems will not fire when do perform a column sorting right after the SfDataGrid has loaded all the 99 records on screen.

Regards,
CT

Attachment: sample_9736735e.zip


SK Suriya Kalidoss Syncfusion Team April 10, 2018 12:46 PM UTC

  
Hi Chang Chiew Thou, 
 
We have checked your sample and you are applying custom sorting to our SfDataGrid. Also while sorting you have called Initialize method(InitProfiles()). In this method you have loaded the records to our SfDataGrid using IncrementalList collection. Could you please confirm the reason for calling this method ? If you need to apply only the custom sorting to our SfDataGrid, please remove this method call and apply the custom sorting; it will be working properly. Otherwise please share more details about this method call, that will be help us to provide the solution. Please refer the code snippet for details. 
 
Code snippet: 
public void SortProfiles(string columnName, ListSortDirection direction) 
        { 
           // this.InitProfiles();   
            this.manager.Sort(columnName, direction); 
        } 
 
 
We had attached working sample for your reference and you can download it from the below link.  
 
Regards, 
Suriya K 



CC CT CHANG April 10, 2018 11:40 PM UTC

Hi Suriya,

Because I am using the IncrementalList<T> for lazy loading. So, I have to reinitialised the data source through InitProfiles() method each time user tapped on the SfDataGrid column header. Otherwise, my display data will not be correct.

This is because, the SfDataGrid sorting only applied to those records that already loaded into the SfDataGrid, which will excluded those in database which yet load into SfDataGrid. (correct me if I am wrong)

Example:
  1. InitProfiles, and load the first 30 records.
  2. Scroll all the way down until LoadMoreItems fire, and load the next 30 records.
  3. Now, it will have 60 records loaded on SfDataGrid.
  4. But, in the data source, there are total of 99 records. Which mean those records from ID: 61  ~  99 have yet load into SfDataGrid.
  5. At this point, if user tapped on the SfDataGrid column header and perform a records sorting. E.g. sort by ID in descending order from 99 ~ 1.
  6. If I using the SfDataGrid sorting function, those display records will be from ID 60 ~ 1.
  7. But, I expected it to be 99 ~ 1.
  8. Therefore, I have to reinitialise the data source object IncrementalList<T> via InitProfiles() method.
Hope this explain why I have to reinitialise the IncrementalList<T> object and rebind it to SfDatagrid.ItemsSource property.

Regards,
CT


SK Suriya Kalidoss Syncfusion Team April 16, 2018 12:55 AM UTC

  
Hi Chang, 
  
We had analyzed your query. We have prepared sample based on your requirement and the sample is working fine 
  
We have attached working sample for your reference and you can downloading it from the below link. 
  
  
Regards, 
Suriya 



CC CT CHANG April 18, 2018 10:21 PM UTC

Thank Suriya,

I will take a look on the sample code and get back to you shortly.

Regards,
CT


SK Suriya Kalidoss Syncfusion Team April 20, 2018 01:50 AM UTC

Hi Chang, 
    Thanks for the update. Please let us know if you require further assistance. 
Regards, 
Suriya K 


Loader.
Up arrow icon