Sorting GroupByRows in the WinGrid by the Number of Child Rows

Mike Saltzman / Thursday, July 2, 2009

Introduction

Using OutlookGroupBy, UltraWinGrid allows you to group rows with similar values together just like Microsoft Outlook.

The way grouping works is that the grid will sort the column and then loop through the rows to find matching values. Thus, the GroupByRows are sorted in the same order in which the value of the column are sorted. For example, if the column contains string data, then the rows of the grid and the GroupByRows are sorted alphabetically.

But suppose you want to make it easier for your users to see which groups have the most (or least) items. It would be useful in a case like this to sort the GroupByRows by the number of rows in the group, rather than by the value. You can do this using the GroupByComparer property on the UltraGridColumn.

The GroupByComparer

The GroupByComparer is a class which implements the IComparer interface. This is a very simple interface with only a single method: Compare. The Compare method in this case will be called with 2 UltraGridGroupByRow objects and it is the task of the implementor to return a value which indicates which value is the greater (or 0 if the values are equal).

In this case, we will use the UltraGridGroupByRow.Rows.Count property to determine the number of child rows for each UltraGridGroupByRow and return a comparison based on those values. So it might look something like this:

public class ChildRowCount_GroupComparer 
        : IComparer
    {
        #region IComparer Members

        int IComparer.Compare(object x, object y)
        {
            // Cast x and y into UltraGridGroupByRow objects. 
            // We can assume that they are of the correct type as long as this comparer is 
            // used for the GroupByRowComparer property on a grid column.
            //
            UltraGridGroupByRow groupByRowX = (UltraGridGroupByRow)x;
            UltraGridGroupByRow groupByRowY = (UltraGridGroupByRow)y;

            // Get the count of the child rows for each. 
            //
            int rowCountX = groupByRowX.Rows.Count;
            int rowCountY = groupByRowY.Rows.Count;

            // Compare. 
            //
            return rowCountX.CompareTo(rowCountY); 
        }

        #endregion
    }

Assigning it to the Columns

Assigning a GroupByComparer to a column is a simple property setting. It is recommend that you do it in an event that fires before the grouping takes place. The InitializeLayout event of the grid is ideal for this purpose.

Here’s an example of what the InitializeLayout event might look like. This code sets up the grid to allow OutlookGroupBy, groups by the “Name” column, and assigns a GroupByComparer to every column in the band.

Note that it is not necessary to create more than one instance of the IComparer. You can use the same instance for as many columns as you like, even if they are in different grids.

Also note that the sample is applying the IComparer to every column. This is not necessarily required. You could, if you like, only apply the IComparer to one or only a few columns. It must be applied to those columns whose group sorting you wish to change. It is also possible to apply different IComparers to different columns.

private void ultraGrid1_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e)
{
    // Store the layout in a member variable to save on typing.
    //
    UltraGridLayout layout = e.Layout;

    // Set up the grid to do grouping.
    //
    layout.ViewStyleBand = ViewStyleBand.OutlookGroupBy;

    // Save the band in a member variable to save on typing.
    //
    UltraGridBand band = layout.Bands[0];

    // Sort and group by the "Name" column.
    //
    band.SortedColumns.Add("Name", false, true);

    // Create an instance of the ChildRowCount_GroupComparer. This is a class which
    // implements IComparer. It examines two UltraGridGroupByRows and returns a comparison
    // result based on the number of child rows that each UltraGridGroupByRow has.
    //
    ChildRowCount_GroupComparer childRowCount_GroupComparer = new ChildRowCount_GroupComparer();

    // Apply the ChildRowCount_GroupComparer to the columns in the band.
    //
    // Note that we only need one instance of the ChildRowCount_GroupComparer for all
    // columns. We could even use the same comparer for columns in different bands or
    // even different grid controls.
    //
    // Also note that we are applying the ChildRowCount_GroupComparer to every column in
    // the band so that the GroupByRows will always be sorted by number of child rows,
    // no matter which column (or columns) are grouped.
    //
    foreach (UltraGridColumn column in band.Columns)
    {
        column.GroupByComparer = (IComparer)childRowCount_GroupComparer;
    }
}
WinGrid - Sorting GroupByRows By Child Row Count CS.zip