This is a migrated thread and some comments may be shown as answers.

Grouping by more than one property and displaying on group header

1 Answer 234 Views
ListView
This is a migrated thread and some comments may be shown as answers.
Cleanwatts
Top achievements
Rank 1
Cleanwatts asked on 11 Apr 2018, 05:33 PM

I have a list of items that I would like to group by several property. To do that I must use DelegateGroupDescriptor instead of PropertyGroupDescriptor. That part does not seem to be complicated.

hat I don't know how to achieve (and have found no examples on to do it) is to display information on the grouping properties on the group header. Is this possible? If so, how can it be done?

1 Answer, 1 is accepted

Sort by
0
Lance | Manager Technical Support
Telerik team
answered on 13 Apr 2018, 07:54 PM
Hello VPS,

You can use the GroupHeaderTemplate to define a cusotm UI for the group header. Note that the binding context of the header is the key value of the group as a display string, so you you just use an empty Binding definition. See the RadListView Grouping documentation for a full example, here's a high level snippet

<telerikDataControls:RadListView>
    <telerikDataControls:RadListView.GroupHeaderTemplate>
        <DataTemplate>
            <StackLayout>
                <Label Text="{Binding }"/>
            </StackLayout>
        </DataTemplate>
    </telerikDataControls:RadListView.GroupHeaderTemplate>
</telerikDataControls:RadListView>


If you need to convert it to a different display value, you can use an IValueConverter.  For example, if you were grouping a DateTime by month, you'd only get a numeric value for the group key. In this case, you can use a converter to get the month name from that integer:



Here's the code for the above example:

             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:telerikDataControls="clr-namespace:Telerik.XamarinForms.DataControls;assembly=Telerik.XamarinForms.DataControls"
             xmlns:listView="clr-namespace:Telerik.XamarinForms.DataControls.ListView;assembly=Telerik.XamarinForms.DataControls"
             xmlns:portable="clr-namespace:GroupingFeatures.Portable;assembly=GroupingFeatures.Portable"
             x:Class="GroupingFeatures.Portable.StartPage">
 
    <ContentPage.Resources>
        <ResourceDictionary>
            <portable:MonthIntToMonthNameConverter x:Key="IntToMonthNameConverter" />
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.BindingContext>
        <portable:ViewModel />
    </ContentPage.BindingContext>
 
 
    <telerikDataControls:RadListView x:Name="listView"
                      BackgroundColor="White"
                      ItemsSource="{Binding Source}"
                      SelectionMode="None">
        <telerikDataControls:RadListView.GroupHeaderTemplate>
            <DataTemplate>
                <Grid BackgroundColor="DodgerBlue"
                      Padding="5">
                    <Label Text="{Binding Converter={StaticResource IntToMonthNameConverter}}"
                        TextColor="WhiteSmoke" />
                </Grid>
            </DataTemplate>
        </telerikDataControls:RadListView.GroupHeaderTemplate>
        <telerikDataControls:RadListView.ItemTemplate>
            <DataTemplate>
                <listView:ListViewTextCell Text="{Binding Sender}"
                               Detail="{Binding Subject}" />
            </DataTemplate>
        </telerikDataControls:RadListView.ItemTemplate>
    </telerikDataControls:RadListView>
</ContentPage>

namespace GroupingFeatures.Portable
{
    public partial class StartPage : ContentPage
    {
        public StartPage()
        {
            InitializeComponent();
 
            listView.GroupDescriptors.Add(new DelegateGroupDescriptor{KeyExtractor = MonthNumberExtractor});
        }
 
        private static object MonthNumberExtractor(object arg)
        {
            if(arg is Mail item)
                return item.Sent.Month;
 
            return null;
        }
    }
     
    internal class MonthIntToMonthNameConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is int monthIndex)
            {
                return DateTimeFormatInfo.CurrentInfo.GetAbbreviatedMonthName(monthIndex);
            }
 
            return "other header";
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
 
    public class Mail : NotifyPropertyChangedBase
    {
        bool isUnread;
 
        public DateTime Sent { get; set; }
        public string Sender { get; set; }
        public string Subject { get; set; }
        public bool IsUnread
        {
            get => isUnread;
            set
            {
                if (this.isUnread == value) return;
                isUnread = value;
                OnPropertyChanged();
            }
        }
    }
 
    public class ViewModel
    {
        public ViewModel()
        {
            this.Source = new ObservableCollection<Mail> {
                new Mail{ Sender = "Terry Tye",  Subject = "Re: Summer Vacation" , IsUnread = true, Sent = DateTime.Now.AddMonths(-1)},
                new Mail{ Sender = "Felicia Keegan",  Subject = "Seminar Invitation", IsUnread = true, Sent = DateTime.Now.AddMonths(-2)},
                new Mail{ Sender = "Jared Linton",  Subject = "Discount code", Sent = DateTime.Now.AddMonths(-2)},
                new Mail{ Sender = "Mark Therese",  Subject = "Quick feedback", IsUnread = true, Sent = DateTime.Now.AddMonths(-3)},
                new Mail{ Sender = "Elvina Randall",  Subject = "Happy Birthday!", Sent = DateTime.Now.AddMonths(-3)},
                new Mail{ Sender = "Emilia Porter",  Subject = "Check the attachment", IsUnread = true, Sent = DateTime.Now.AddMonths(-3)},
                new Mail{ Sender = "Jared Linton",  Subject = "Gillian Flynn", Sent = DateTime.Now.AddMonths(-2)},
                new Mail{ Sender = "Felicia Keegan",  Subject = "Re: Summer Vacation", Sent = DateTime.Now.AddMonths(-1)},
                new Mail{ Sender = "Felicia Keegan",  Subject = "Pictures", Sent = DateTime.Now.AddMonths(-1)},
            };
        }
 
        public ObservableCollection<Mail> Source { get; set; }
    }
}


Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
ListView
Asked by
Cleanwatts
Top achievements
Rank 1
Answers by
Lance | Manager Technical Support
Telerik team
Share this question
or