SfListView loses group headers when the datasource is refreshed while it is in a SfShimmer control

I have a ContentPage which is being navigated to from a TabbedPage. When the ContentPage is active it (reloads) the datasource for the SfListview. During this dataload the shimmer is being set to active. When the data loading finishes the the shimmer is set to inactive (false), though on reloading of this data all the SFListView group headers are dissapearing..

When I leave the Shimmer out then it works as normal when reloading the datasource.. This also only seem to happen when I use a CustomView in my shimmer.

*For some reason I cant use the code tags, it messes up the formatting entirely and incorrectly..

My contentPage:

<ContentPage
    x:Class="PCS2.APP.MessageListPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:data="clr-namespace:Syncfusion.DataSource;assembly=Syncfusion.DataSource.Portable"
    xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
    xmlns:shimmer="clr-namespace:Syncfusion.XForms.Shimmer;assembly=Syncfusion.Core.XForms"
    xmlns:sync="clr-namespace:Syncfusion.ListView.XForms;assembly=Syncfusion.SfListView.XForms"
    prism:ViewModelLocator.AutowireViewModel="True"
    NavigationPage.HasNavigationBar="False">
    <ContentPage.Content>
        <shimmer:SfShimmer IsActive="{Binding ShowShimmer}" VerticalOptions="Fill">
            <shimmer:SfShimmer.CustomView>
<!-- some custom shimmer -->
                <shimmer:ShimmerView HeightRequest="40" IsVisible="{Binding ShowShimmer}" />
            </shimmer:SfShimmer.CustomView>
            <shimmer:SfShimmer.Content>
                <Grid Margin="0">
                    <sync:SfListView
                        x:Name="listView"
                        AllowGroupExpandCollapse="True"
                        FocusBorderThickness="0"
                        GroupHeaderSize="40"
                        IsStickyGroupHeader="True"
                        ItemSize="60"
                        ItemsSource="{Binding MessageListData}"
                        SelectionBackgroundColor="#ECECEC"
                        <sync:SfListView.DataSource>
                            <data:DataSource>
                                <data:DataSource.GroupDescriptors>
                                    <data:GroupDescriptor PropertyName="ClientName" />
                                </data:DataSource.GroupDescriptors>
                                <data:DataSource.SortDescriptors>
                                    <data:SortDescriptor Direction="Descending" PropertyName="LastMessageDate" />
                                    <data:SortDescriptor Direction="Ascending" PropertyName="ClientName" />
                                </data:DataSource.SortDescriptors>
                            </data:DataSource>
                        </sync:SfListView.DataSource>
                        <sync:SfListView.GroupHeaderTemplate>
                            <DataTemplate>
                                <ViewCell>
                                    <ViewCell.View>
<!-- omitted other XAML -->
                                    </ViewCell.View>
                                </ViewCell>
                            </DataTemplate>
                        </sync:SfListView.GroupHeaderTemplate>
                        <sync:SfListView.ItemTemplate>
                            <DataTemplate>
                                <ViewCell>
                                    <ViewCell.View>                                     
<!-- omitted other XAML -->
                                    </ViewCell.View>
                                </ViewCell>
                            </DataTemplate>
                        </sync:SfListView.ItemTemplate>
                    </sync:SfListView>
                </Grid>
            </shimmer:SfShimmer.Content>
        </shimmer:SfShimmer>
    </ContentPage.Content>
</ContentPage>


Backend (reloading of data):

protected override async void OnIsActive()
{
ShowShimmer = true;
await Task.Delay(2000);

try
{
// reinitialize data
var _messages = await App.Database.GetMessagesDataAsync(null, null);

var _messagesList = _messages
.GroupBy(g => new
{
// some properties
})
   .Select(group => new MessageListModel
   {
   // some properties
   }).ToList();

if (_messagesList != null)
{
MessageListData = _messagesList;
}
}
catch (Exception ex)
{
ShowShimmer = false;
throw;
}
finally
{
ShowShimmer = false;
}
}



1 Reply 1 reply marked as answer

LN Lakshmi Natarajan Syncfusion Team May 31, 2021 04:06 AM UTC

Hi Nicolas, 
 
Thank you for using Syncfusion products. 
 
We have checked the reported query “SfListView loses group headers when the datasource is refreshed while it is in a SfShimmer control” from our side. We would like to inform you that when using the SfListView inside SfShimmer, the ListView.ItemsSource becomes null. Also, when the ItemsSource changed to null at run time, the DataSource.GroupDescriptor and DataSource.SortDescriptor will be cleared. This is the expected behavior in SfListView.  
 
Please refer to our user guidance document regarding the same, 
UG links: 
 
So, we need to add the GroupDescriptor and SortDescriptor again to retain grouping and sorting. 
 
Please refer to the code snippets to achieve your requirement, 
public class ContactsViewModel : INotifyPropertyChanged 
{ 
    ... 
 
    public DataSource ListDataSource { get; set; } 
 
    public ContactsViewModel() 
    { 
        DataServices = new RestService(); 
        ListDataSource = new DataSource(); 
        UserInfo = new ObservableCollection<UserDetails>(); 
    } 
 
    private void AddDataSource() 
    { 
        ListDataSource.Source = UserInfo; 
        ListDataSource.GroupDescriptors.Clear(); 
        ListDataSource.SortDescriptors.Clear(); 
        ListDataSource.GroupDescriptors.Add(new GroupDescriptor() { PropertyName = "ClientName" }); 
        ListDataSource.SortDescriptors.Add(new SortDescriptor() { PropertyName = "LastMessageDate", Direction = Syncfusion.DataSource.ListSortDirection.Descending }); 
        ListDataSource.SortDescriptors.Add(new SortDescriptor() { PropertyName = "ClientName", Direction = Syncfusion.DataSource.ListSortDirection.Ascending }); 
    } 
 
    public async void OnIsActive() 
    { 
        ShowShimmer = true; 
        await Task.Delay(2000); 
 
        try 
        { 
            var _messages = await DataServices.GetDataAsync(); 
            ... 
            if (_messages != null) 
            { 
                UserInfo = _messages; 
            } 
        } 
        catch (Exception ex) 
        { 
            ShowShimmer = false; 
            throw; 
        } 
        finally 
        { 
            AddDataSource(); 
            ShowShimmer = false; 
        } 
    } 
} 
 
Also, update the DataSource and ItemsSource when BindingContext is not null as mentioned below, 
public class SfListViewBehavior : Behavior<SfListView> 
{ 
    SfListView ListView; 
 
    protected override void OnAttachedTo(SfListView bindable) 
    { 
        ListView = bindable; 
        ListView.BindingContextChanged += ListView_BindingContextChanged; 
        base.OnAttachedTo(bindable); 
    } 
 
    private void ListView_BindingContextChanged(object sender, EventArgs e) 
    { 
        var bc = ListView.BindingContext as ContactsViewModel; 
 
        if (bc != null) 
        { 
            ListView.DataSource = bc.ListDataSource; 
            ListView.ItemsSource = bc.ListDataSource.Source; 
        } 
    } 
} 
 
We have prepared a sample based on the code snippets provided and attached in the following link, 
 
Please refer to our online documentation regarding the same from the following link, 
 
Please let us know if you need further assistance. 
 
Regards, 
Lakshmi Natarajan 


Marked as answer
Loader.
Up arrow icon