Articles in this section
Category / Section

How to customize the ListView grouping with grid columns in Xamarin.Forms (SfListView)

2 mins read

You can customize grouping by a Comparer in GroupDescriptor and GroupHeader using the GroupHeaderTemplate with converter.

Here, the GroupHeader is customized as ListViewItem using the converter in GroupHeaderTemplate.

<syncfusion:SfListView x:Name="listView" GroupHeaderSize="300"
    AutoFitMode="DynamicHeight"
    SelectionMode="Single"
    ItemsSource="{Binding MemberDetails}">
    <syncfusion:SfListView.GroupHeaderTemplate>
        <DataTemplate>
            <StackLayout BackgroundColor="LightGray">
                <Image x:Name="ScrumMasterImage" Source="{Binding 
                    Converter={StaticResource Converter}, 
                    ConverterParameter=ScrumMasterImage}"
                    VerticalOptions="Center"
                    HeightRequest="80" WidthRequest="80"
                    HorizontalOptions="CenterAndExpand"
                    Margin="10" />
                <Label x:Name="ScrumMasterRole" Text="{Binding 
                    Converter={StaticResource Converter}, 
                    ConverterParameter=ScrumMasterRole}" 
                    FontSize="20"   
                    HorizontalOptions="CenterAndExpand" 
                    VerticalOptions="Center"/>
                <Label x:Name="ScrumMasterName" Text="{Binding 
                    Converter={StaticResource Converter}, 
                    ConverterParameter=ScrumMasterName}" 
                    FontSize="18"
                    Padding="0,0,0,10"
                    HorizontalOptions="CenterAndExpand" 
                    VerticalOptions="Center"/>
            </StackLayout>
        </DataTemplate>
    </syncfusion:SfListView.GroupHeaderTemplate>
</syncfusion:SfListView>

Converter, which designs the group header.

class Converter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return null;
 
        string id = parameter as string;
 
        var groupResult = value as GroupResult;
        foreach (var item in groupResult.Items)
        {
            if(id == "ScrumMasterImage")
            {
                return (item as TeamInfo).MemberImage;
            }
            else if(id == "ScrumMasterRole")
            {
                return (item as TeamInfo).Role;
            }
            else if (id == "ScrumMasterName")
            {
                return (item as TeamInfo).MemberName;
            }
        }
        return null;
    }
 
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

The GridLayout defined in the LayoutManager with column count as 2 using the SpanCount property.

<syncfusion:SfListView x:Name="listView">
    <syncfusion:SfListView.LayoutManager>
        <syncfusion:GridLayout SpanCount="2"/>
    </syncfusion:SfListView.LayoutManager>
</syncfusion:SfListView>

The GroupDescriptor defined with comparer to sort the specific group always to be at the top of the rows.

public class Behavior : Behavior<SfListView>
{
    protected override void OnAttachedTo(SfListView bindable)
    {
        bindable.DataSource.GroupDescriptors.Add(new GroupDescriptor()
        {
            PropertyName = "IsScrumMaster",
            Comparer = new GroupComparer()
        });
        base.OnAttachedTo(bindable);
    }
}
 
public class GroupComparer : IComparer<GroupResult>
{
    public int Compare(GroupResult x, GroupResult y)
    {
        if (x.Count > y.Count)
        {
            return 1;
        }
        else if (x.Count < y.Count)
        {
            return -1;
        }
 
        return 0;
    }
}

QueryItemSize to reset the Height of the groups that are not needed to show in the view to zero.

public class Behavior : Behavior<SfListView>
{
    protected override void OnAttachedTo(SfListView bindable)
    {
        bindable.QueryItemSize += Bindable_QueryItemSize;
    }
    private void Bindable_QueryItemSize(object sender, QueryItemSizeEventArgs e)
    {
        var bindingContext = (sender as SfListView).BindingContext as TeamInfoRepository;
        var collection = bindingContext.MemberDetails;
        var type = e.ItemType;
        if (type == ItemType.GroupHeader && (bool)(e.ItemData as GroupResult).Key) ;
        else if (type == ItemType.GroupHeader 
            && !(bool)(e.ItemData as GroupResult).Key)
        {
            e.ItemSize = 0;
            e.Handled = true;
        }
        if (type == ItemType.Record)
        {
            var isManager = (e.ItemData as TeamInfo).IsScrumMaster;
            if (isManager)
            {
                e.ItemSize = 0;
                e.Handled = true;
            }
        }
    }
    protected override void OnDetachingFrom(SfListView bindable)
    {
        bindable.QueryItemSize -= Bindable_QueryItemSize;
        base.OnDetachingFrom(bindable);
    }
}

Output

Custom GroupHeader

Download sample from GitHub

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please  to leave a comment
Access denied
Access denied