SfList SortDescriptor not sorting

I have an SfList and I'm using SortDescriptor like this:

                        <syncfusion:SfListView.DataSource>
                          <data:DataSource>
                            <data:DataSource.SortDescriptors>
                              <data:SortDescriptor PropertyName="TimeToRespond" Direction="Ascending" />
                            </data:DataSource.SortDescriptors>
                          </data:DataSource>
                        </syncfusion:SfListView.DataSource>

But it doesn't sort when TimeToRespond updates. I tried changing DataSource to:

        <data:DataSource LiveDataUpdateMode="AllowDataShaping">

And then it did start sorting - as soon as TimeToRespond changed in the model the ListView items would move. However, we saw ListView items on top of each other, like this:


And we also saw gaps where the first listview item would appear halfway down the list with the top of the listview just blank.

So I don't think AllowDataShaping is the answer I'm looking for.

Any tips on getting sorting to work?

5 Replies

LN Lakshmi Natarajan Syncfusion Team April 27, 2020 10:12 AM UTC

 
Thank you for using Syncfusion products. 
 
#Regarding ListView doesn't sort when TimeToRespond updates query 
 
We have checked the reported query “SfListView SortDescriptor not sorting” from our end. We would like to inform you that you need to use LiveDataUpdateMode as AllowDataShaping for DataSource to update the dynamic changes in sorting and grouping. This is the expected behavior in ListView Sorting. We will update the same in our user guidance document shortly. 
 
#Regarding ListView items on top of each other query 
 
We have checked the reported query from our end. But, we are unable to reproduce the reported issue from our end. Could you please ensure whether the PropertyChanged event is invoked for TimeToRespond property? 
 
#Regarding gaps where the first listview item would appear halfway down the list with the top of the listview just blank query 
 
We could not reproduce the reported issue in our simple sample. Could you please share more details about this issue and share the replication procedure to reproduce the issue with code snippets to check on it further.  
 
Also, we suggest you to use AutoFitMode as DynamicHeight to update the item size at run time. Please refer our UG document regarding the same in the following link, 
 
 
Meanwhile, we have attached the tested sample in the following link, 
 
 
Please check the sample and let us know if you still facing the same issue? If not, please modify our sample to reproduce the reported issue and revert us back with the following details, 
  • Share the ListView related templates
  • Share run time TimeToRespond property update code snippet
 
It will be helpful for us to check on it and provide you the solution as soon as possible. 
 
Regards, 
Lakshmi Natarajan 
 



BD Brad Dean April 27, 2020 07:17 PM UTC

I added LiveDataUpdateMode="AllowDataShaping". However, this caused another issue. The SfList is bound to an ObservableCollection in a .Net library. As soon as TimeToRespond in one of the objects is updated I get this error:

"Only the original thread that created a view hierarchy can touch its views"

This problem is the .Net library where the ObservableCollection and the model that holds TimeToResponse lives does not have a reference to Xamarin.Forms. So I can't update inside a Device.BeginOnUIThread.

The error is happening at Syncfusion.ListView.XForms.Android.ListViewItemRenderer.OnElementPropertyChanged. Is there a way to tell that method to fire on the UI thread?


LN Lakshmi Natarajan Syncfusion Team April 28, 2020 07:06 AM UTC

Hi Brad, 
 
Thank you for the update. 
 
We have checked the reported query “Crash when updating property” from our end. We would like to inform you that the Layout will be updated when making changes to the ObservableCollection which bounds to the ListView.ItemsSource. The reported issue occurs when making changes in the collection in the secondary thread, the UI threads gets interrupted and cause the exception which restrict the layouts in the application.   
  
Please refer the same mentioned in the following links,  
 
We suggest you to use behavior class where you can get the the Xamarin.Forms reference and update the property in the main thread to overcome the reported issue in sample level. Please refer the following link for Behavior in Xamarin.Forms, 
 
We hope this helps. If not, please share the following details which would be helpful for us to check on it and provide you the solution as soon as possible, 
  • Share code snippets of ListView related templates
  • Share the code snippets of ViewModel and Model class
  • Share code snippets of TimeToRespond property update
 
Regards, 
Lakshmi Natarajan 
 



BD Brad Dean April 28, 2020 03:55 PM UTC

To give some background - the .Net Standard library is a WebSocket implementation. So it is updating the collection. The collection cannot be updated inside a Binding in the Xamarin project since only the WebSocket knows when to do the updating. A Xamarin reference can't be added to the .Net Standard library because it's shared with other (non Xamarin) projects.

I'm attaching a sample that uses a Timer in place of WebSockets to simulate the problem.

Attachment: SyncfusionSample_fff507e2.zip


LN Lakshmi Natarajan Syncfusion Team April 29, 2020 09:15 PM UTC

Hi Brad, 
 
Thank you for the update. 
 
We have checked the reported query in the provided sample. We could reproduce the issue in this sample. You can overcome the reported issue by Code sharing the MessagingLibrary project. Using this code sharing practice, you can share the same project with multiple platforms using conditional compilation. Please follow the below steps to achieve your requirement, 
 
1. Install Xamain.Forms nuget package in the MessagingLibrary project. 
2. Set Conditional compilation symbol for Xamarin.Forms. To enable this, go to Properties -> Build -> Type XForms in the conditional compilation symbols field. 
 
 
3. Update the property changed code in the main thread using Device.BeginInvokeMethod. Please refer the following code snippet for more reference, 
        protected void OnPropertyChanged<TProperty>(Expression<Func<TProperty>> projection) 
        { 
            OnPropertyChanged(new PropertyChangedEventArgs(projection.PropertyName()).PropertyName); 
        } 
        protected bool SetProperty<T>(ref T backingStore, T value, [CallerMemberName]string propertyName = "", Action onChanged = null) 
        { 
            if (EqualityComparer<T>.Default.Equals(backingStore, value)) 
                return false; 
 
            backingStore = value; 
#if XForms   
                Xamarin.Forms.Device.BeginInvokeOnMainThread(() => 
                { 
                    onChanged?.Invoke(); 
                    OnPropertyChanged(propertyName); 
                }); 
#else 
            onChanged?.Invoke(); 
            OnPropertyChanged(propertyName); 
#endif 
            return true; 
        } 
 
Please refer the document regarding conditional compilation in Xamarin from the following link, 
 
We have modified the provided sample and attached in the following link, 
 
Please check the sample and let us know if this helps. 
 
Regards, 
Lakshmi Natarajan 
 


Loader.
Up arrow icon