Category / Section
How to add footer for groups in Xamarin.Forms ListView (SfListView)
2 mins read
You can add a group footer by handling the visibility of the item template elements in Xamarin.Forms SfListView.
XAML
Load the element in the SfListView.ItemTemplate as a footer and handle the visibility of the element based on the group items count. When reordering the item, customise the DragItemTemplate and update the refresh the item 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 in 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 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); }); } } }