SfListView Group Footer?

Hi,

Does a group footer option exist somehow for the SfListView control?

If not, is it possible to put in a feature request for it?

Cheers,
Mark

4 Replies 1 reply marked as answer

LN Lakshmi Natarajan Syncfusion Team January 13, 2021 01:31 PM UTC

Hi Mark, 
 
Thank you for using Syncfusion support. 
 
We have checked the reported query “How to add Group footer for SfListView” from our side. You can achieve your requirement by loading an element in the SfListView.ItemTemplate as footer and handle the visibility of the element. When reordering the item, customize the DragItemTemplate and update the refresh the items to update the footer item. 
<syncfusion:SfListView x:Name="listView" AutoFitMode="DynamicHeight" ItemsSource="{Binding ContactsInfo}" DragStartMode="OnHold"> 
    <syncfusion:SfListView.DataSource> 
        <data:DataSource> 
            <data:DataSource.GroupDescriptors> 
                <data:GroupDescriptor PropertyName="ContactType"/> 
            </data:DataSource.GroupDescriptors> 
        </data:DataSource> 
    </syncfusion:SfListView.DataSource> 
    <syncfusion:SfListView.ItemTemplate > 
        <DataTemplate> 
            <StackLayout> 
                <Grid x:Name="itemDetails"> 
                    ... 
                </Grid> 
                <StackLayout x:Name="groupFooter" BackgroundColor="AliceBlue" IsVisible="{Binding ., Converter={StaticResource FooterVisibilityConverter}, ConverterParameter={x:Reference listView}}"> 
                    <Label Text="{Binding ., Converter={StaticResource FooterTextConverter}, ConverterParameter={x:Reference listView}}" HeightRequest="30" BackgroundColor="Transparent" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"/> 
                </StackLayout> 
            </StackLayout> 
        </DataTemplate> 
    </syncfusion:SfListView.ItemTemplate> 
    <syncfusion:SfListView.DragItemTemplate> 
        <DataTemplate> 
            <Grid x:Name="dragItem"> 
                ... 
            </Grid> 
        </DataTemplate> 
    </syncfusion:SfListView.DragItemTemplate> 
    <syncfusion:SfListView.GroupHeaderTemplate> 
        <DataTemplate> 
            <StackLayout x:Name="groupHeader" BackgroundColor="#E4E4E4"> 
                <Label Text="{Binding Key}" FontSize="22" FontAttributes="Bold" VerticalOptions="CenterAndExpand" HorizontalOptions="Start" Margin="20,0,0,0" /> 
            </StackLayout> 
        </DataTemplate> 
    </syncfusion:SfListView.GroupHeaderTemplate> 
</syncfusion:SfListView> 
C# 
Returns the visibility as true for the last item of the group, otherwise false. 
public class FooterVisibilityConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
        var listView = parameter as SfListView; 
 
        if (value == null || listView.DataSource.Groups.Count == 0) 
            return false; 
 
        var groupHelper = new GroupHelper(listView); 
        var groupresult = groupHelper.GetGroup(value); 
        var dropGroupList = groupresult.GetType().GetRuntimeProperties().FirstOrDefault(method => method.Name == "ItemList").GetValue(groupresult) as List<object>; 
        var lastItem = dropGroupList[dropGroupList.Count - 1] as Contacts; 
        return dropGroupList[dropGroupList.Count - 1] == value; 
    } 
} 
 
internal class GroupHelper 
{ 
    private SfListView ListView; 
         
    public GroupHelper(SfListView sfListView) 
    { 
        ListView = sfListView; 
    } 
 
    public GroupResult GetGroup(object itemData) 
    { 
        GroupResult itemGroup = null; 
 
        foreach (var item in this.ListView.DataSource.DisplayItems) 
        { 
            if (item == itemData) 
                break; 
 
            if (item is GroupResult) 
                itemGroup = item as GroupResult; 
        } 
        return itemGroup; 
    } 
} 
 
C# 
Refresh the items using SfListView.RefreshListViewItems method in the ItemDragging event. 
public class Behavior : Behavior<ContentPage> 
{ 
    SfListView ListView; 
 
    protected override void OnAttachedTo(ContentPage bindable) 
    { 
        ListView = bindable.FindByName<SfListView>("listView"); 
        ListView.ItemDragging += ListView_ItemDragging; 
        base.OnAttachedTo(bindable); 
    } 
 
    private void ListView_ItemDragging(object sender, ItemDraggingEventArgs e) 
    { 
        if(e.Action == DragAction.Drop) 
        { 
            Device.BeginInvokeOnMainThread(() => 
            { 
                ListView.RefreshListViewItem(-1, -1, true); 
            }); 
        } 
    } 
} 
 
We have prepared a sample based on your requirement and attached in the following link, 
 
Please let us know if you need further assistance. 
 
Lakshmi Natarajan 
 


Marked as answer

RA Raymond August 19, 2021 12:40 PM UTC

Hi

I'm trying to add group footer and used this example but found an issue when adding new items to the list at runtime. As you can see in the screenshot, when new item is added, it shows with its own group footer. It only seems to be an issue for the group that is currently visible, once you scroll it groups correctly. Does anyone have an idea of why this would be happening and how to fix it? 

Are there any plans to add built in support to SFListView for group footers?

list grouping.PNG

Full repo: https://github.com/raytechpro/ListViewXamarin/

To replicate, scroll the list so a group footer is visible and then keep pressing the Add Item button until an item is added to that group

Thanks

Ray





LN Lakshmi Natarajan Syncfusion Team August 23, 2021 04:14 AM UTC

Hi Raymond, 
 
Thank you for using Syncfusion products. 
 
We have checked the reported query “Group footer issue when adding new items to the list at runtime” from our side. We would like to inform you that we were able to reproduce the reported scenario at our side. We will check for the possibilities to overcome the reported scenario and update you further details in two business days (August 24, 2021). We appreciate your patience until then. 
 
Lakshmi Natarajan 
 



LN Lakshmi Natarajan Syncfusion Team August 24, 2021 11:23 AM UTC

Hi Raymond, 
 
Thank you for your patience. 
 
We have checked the reported query “Group footer issue when adding new items to the list at runtime” from our side. We would like to inform you that when a new item is added to the group, the old items are unaware of the new addition, resulting in the reported scenario. When adding a new item, we can achieve the reported scenario by refreshing the group items.  
 
We can get the group details and refresh the items in the collection changed event as shown below. 
public class Behavior : Behavior<ContentPage> 
{ 
    protected override void OnAttachedTo(ContentPage bindable) 
    { 
        ListView = bindable.FindByName<SfListView>("listView"); 
 
        ViewModel = bindable.BindingContext as ContactsViewModel; 
        ViewModel.ContactsInfo.CollectionChanged += ContactsInfo_CollectionChanged; 
 
        ListView.ItemDragging += ListView_ItemDragging; 
        base.OnAttachedTo(bindable); 
    } 
 
    private void ContactsInfo_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add) 
        { 
            //Get the group details of the new added item and refresh the group footer. 
            var groupHelper = new GroupHelper(ListView); 
 
            var key = ListView.DataSource.DisplayItems.FirstOrDefault(x => 
            { 
                if(x is Contacts contact) 
                { 
                    if(contact.ContactType == (e.NewItems[0] as Contacts).ContactType) 
                    { 
                        return true; 
                    } 
                } 
 
                return false; 
            }); 
 
            var groupresult = groupHelper.GetGroup(key); 
            var dropGroupList = groupresult.GetType().GetRuntimeProperties().FirstOrDefault(method => method.Name == "ItemList").GetValue(groupresult) as List<object>; 
            var lastItem = dropGroupList[dropGroupList.Count - 1]; 
            var prevIndex = ListView.DataSource.DisplayItems.IndexOf(lastItem); 
                 
            Device.BeginInvokeOnMainThread(() => 
            { 
                ListView.RefreshListViewItem(prevIndex, prevIndex, true); 
            }); 
        } 
    } 
} 
 
We have prepared a sample to achieve your requirement and attached in the following link, 
 
Please let us know if you need further assistance. 
 
Regards, 
Lakshmi Natarajan 


Loader.
Up arrow icon