New to Telerik UI for WinForms? Download free 30-day trial

Sorting group rows by date in RadGridView

Environment

Product Version Product Author
2020.1.113 RadGridView for WinForms Nadya Karaivanova

Description

This tutorial demonstrates how to sort rows in RadGridView when it is grouped by date.

sort-group-rows-by-date.gif

Solution

By default, when you perform grouping, RadGridView sorts the created group rows alphabetically (see Sorting Group Rows article). If you want to sort groups by another criteria it is suitable to use a GroupComparer class. Thus, you can parse each group key to DateTime format and compare the date instead of the string.

A full code snippet is illustrated below:

 public Form1()
        {
            InitializeComponent();

            DataTable dt = new DataTable();
            dt.Columns.Add("Id", typeof(int));
            dt.Columns.Add("StartDate", typeof(DateTime));
            dt.Columns.Add("EndDate", typeof(DateTime));
            DateTime date = new DateTime(2020, 2, 10);
            for (int i = 1; i < 20; i++)
            {
                dt.Rows.Add(i, date.AddHours(i * 12), date.AddDays(i + 1));
            }
            radGridView1.DataSource = dt;

            radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
            radGridView1.Columns[1].FormatString = "{0:dd/MM/yyyy}";
            radGridView1.Columns[2].FormatString = "{0:dd/MM/yyyy}";

            radGridView1.MasterTemplate.GroupPredicate = PerformGrouping;
            radGridView1.MasterTemplate.GroupComparer = new GroupComparer();

        }

        public class GroupComparer : IComparer<Group<GridViewRowInfo>>
        {
            public int Compare(Group<GridViewRowInfo> x, Group<GridViewRowInfo> y)
            {
                if (x.GetType().Name != y.GetType().Name)
                {
                    return x is DataItemGroup<GridViewRowInfo> ? 1 : -1;
                }

                DateTime parsedX;
                DateTime parsedY;
                int result;

                if (DateTime.TryParse(((object[])x.Key).First().ToString(), out parsedX) &&
                    DateTime.TryParse(((object[])y.Key).First().ToString(), out parsedY))
                {
                    result = parsedX.CompareTo(parsedY);
                    DataGroup xGroup = x as DataGroup;
                    if (xGroup != null && xGroup.GroupDescriptor.GroupNames.Count > 0)
                    {
                        if (xGroup.GroupDescriptor.GroupNames.First().Direction == ListSortDirection.Ascending)
                        {
                            return result;
                        }
                    }

                    result = -1 * result;
                    return result;
                }

                return x.Key.ToString().CompareTo(y.Key.ToString());
            }
        }

        private object PerformGrouping(GridViewRowInfo row, int level)
        {
            GroupDescriptor groupDescriptors = this.radGridView1.GroupDescriptors[level];
            object[] key = new object[groupDescriptors.GroupNames.Count];

            for (int k = 0; k < groupDescriptors.GroupNames.Count; k++)
            {
                SortDescriptor descriptor = groupDescriptors.GroupNames[k];
                int index = descriptor.PropertyIndex;

                if (index < 0)
                {
                    continue;
                }

                key[k] = this.GetItemKey(row, descriptor);
            }

            return key;
        }
        private object GetItemKey(GridViewRowInfo item, SortDescriptor descriptor)
        {
            int index = descriptor.PropertyIndex;
            object keyValue = item.Cells[index].Value;

            if (descriptor.PropertyName == "StartDate" || descriptor.PropertyName == "EndDate")
            {
                keyValue = ((DateTime)keyValue).ToShortDateString();
            }

            return keyValue;
        }
In this article