Grid / Data Processing / Grouping
In This Topic
    Grouping
    In This Topic
     About Grouping

    Grouping is only applicable for Table Grid. Grouping is performed after filtering as described in the Data Processing Overview topic. The purpose of grouping is to create a hierarchical organization of the grid rows, such that the rows that reside in each group share some common grouping defined common value.

    The groupings of a Table Grid are defined as a collection of NGroupingRule instances that are contained inside a NGroupingRuleCollection accessible from the NTableGrid.GroupingRules property. Because the Table Grid can have multiple grouping rules, this helps you create hierarchical grids like the one in the following image:

    figure 1. Hierarchical Grid

     

    The NGroupingRule exposes control over the following aspects of the grouping:

    • Row Value - the value by which rows are grouped is controlled by an associated Row Value accessible by the RowValue property.
    • Grouping Header - the grouping rule exposes control over the widget generated as content of the Grouping Header. Each grouping rule is represented by a Grouping Header inside the grouping panel.
    • Grouping Sorting Direction - the grouping rule exposes control over the grouping sorting direction via its SortingDirection property. The NGroupRow instances at each grouping level are always sorted in either ascending or descending manner. The user is able to change the grouping sorting direction by clicking on the sorting button in the Grouping Header.
    • Group Row Content - the grouping rule exposes control over the content generated inside each NGroupingRow. The NGroupingRow can contain multiple snap cells. The NGroupingRow snap cells is exposed via a delegate, which the developer can handle to customize the grouping row content.

    The rest of this topic discusses these aspects in detail

     Grouping Rule and its Row Value

    There is a Row Value associated with each NGroupingRule. The row value is specified by the RowValue property. The purpose of the row value is to define the criteria by which rows are grouped at each specific grouping level. The following code example creates several grouping rules that group by two different data source fields:

    NGroupingRule and Row Value Example
    Copy Code
    NGroupingRule groupByJobTitle = new NGroupingRule();
    groupByJobTitle.RowValue = new NFieldRowValue("JobTitle");
    tableGrid.GroupingRules.Add(groupByJobTitle);
    NGroupingRule groupByName = new NGroupingRule();
    groupByName.RowValue = new NFieldRowValue("Name");
    tableGrid.GroupingRules.Add(groupByName);
    
    The general rule of grouping is that two records belong to the same group, if the grouping rule RowValue produces the same value for these records. That is why the RowValue determines the way in which the grouping works. See Row Values for more information.
     Grouping Rule and the associated Column

    Each grouping rule can be associated with a grid column. The associated column is specified by the NGroupingRule.Column property. There are several things, which happen when a filtering rule is associated with a column:

    • Default Row Value - there is a default row value associated with the grouping rule and it is the row value provided by the column. The following code example creates a grouping rule that groups by the Total column:
      Group By Column
      Copy Code
      // create a grouping rule that groups by the Total column.
      // Note that when the grouping rule is associated with a column, by default it groups by it
      // you can still however set the RowValue to alter the default column grouping, yet keep the Column association.
      NGroupingRule groupByTotal = new NGroupingRule();
      groupByTotal.Column = totalColumn;
      tableGrid.GroupingRules.Add(groupByTotal);
      
    • Visual Interface - the visual interface will indicate that there is a grouping rule associated with the column. For example the context menu of the column will have the Ungroup command:


      figure 2. Column Context menu

    When a column is dragged to the grouping panel, the column is asked to create a grouping rule. By default the column creates a grouping rule that is simply associated the column itself, as shown by the "Group By Column" example. You can however intercept the NColumn.CreateGroupingRuleDelegate delegate to create a custom grouping rule, when the column is dropped in the Groupings Panel

    Custom Column Grouping Rule
    Copy Code
    column.CreateGroupingRuleDelegate = delegate(NColumn theColumn)
    {
        NGroupingRule groupingRule = new NGroupingRule();
        NCustomRowValue<string> rowValue = new NCustomRowValue<string>();
        rowValue.GetRowValueDelegate = delegate(NCustomRowValueGetRowValueArgs<string> getValueArgs)
        {
            switch (Convert.ToString(getValueArgs.DataSource[getValueArgs.Row, "Country"]))
            {
                case "USA":
                case "Canada":
                    return "North America";
                case "Germany":
                case "France":
                    return "Europe";
                default:
                    return "Unknown";
            }
        };
        groupingRule.RowValue = rowValue;
        return groupingRule;
    };
    
     Grouping Panel and Grouping Headers

    Each grouping rule that resides in the NGrid.GroupingRules collection is represented by a grouping header in the grouping panel. The following image shows a Grouping Panel with two grouping headers:


    figure 3. Grouping Panel and Grouping Headers

    The grouping header is represented by an instance of the NGroupingHeader class, which has a Content widget and Sort Order and Remove buttons. The Sort Order button toggles the grouping NGroupingRule.SortingDirection. The Remove button removes the grouping rule from the NGrid.GroupingRules collection.

    The grouping rule is responsible for the creation of the grouping header. When the grouping rule is asked to create a grouping header to represent it in the groupings panel, it raises the CreateGroupingHeaderContent event, which allows you to customize the grouping header. If the user does not handle the CreateGroupingHeaderContent event, by default the content of the grouping header is the same as the column header content and is created by the column. The following code example customizes the grouping header:

    Custom Grouping Header Content
    Copy Code
    NGroupingRule groupingRule = new NGroupingRule();
    groupingRule.CreateGroupingHeaderContent += delegate(NCreateGroupingRuleGroupingHeaderContentArgs arg)
    {
        NPairBox pair = new NPairBox("Birthday", NResources.Image__16x16_Birthday_png);
        arg.GroupingHeaderContent = pair;
    };
    
     Group Rows

    Each group of records is headered by a NGroupRow, which is a row that consists of span cells. You can customize the cells that appear in group row created by the grouping rule, by handling the NGroupingRule.CreateGroupRowCells event:

    Custom GroupRow cells
    Copy Code
    NGroupingRule groupingRule = new NGroupingRule();
    groupingRule.CreateGroupRowCells += delegate(NCreateGroupingRuleGroupRowCellsArgs arg)
    {
        string country = Convert.ToString(arg.GroupRow.GroupValue);
        NGroupRowCell countryCell = new NGroupRowCell(country);
        countryCell.EndXPosition.Mode = ENSpanCellEndXPositionMode.NextCellBeginX;
        NGroupRowCell ordersCountCell = new NGroupRowCell("Orders Count:" + arg.GroupRow.Recordset.Count);
        ordersCountCell.EndXPosition.Mode = ENSpanCellEndXPositionMode.RowEndX;
        ordersCountCell.BeginXPosition.Mode = ENSpanCellBeginXPositionMode.AnchorToEndX;
        arg.GroupRowCells = new NGroupRowCell[] { countryCell, ordersCountCell };
    };
    

    See Group Rows and Span Cells for more information about NGroupRow and the NGroupRowCell.

     Grouping Rules created by Columns

    When a column is dropped in the grouping panel, the column is asked to create a grouping rule that represents this column. By default the column simply creates a grouping rule that is associated with the column (e.g. groups by the column values). You may however want to perform custom grouping for specific columns. In order to do that you need to handle the NColumn.CreateColumnGroupingRule event as shown in the following example:

    Custom grouping rules created by columns
    Copy Code
    column.CreateColumnGroupingRule += delegate(NCreateColumnGroupingRuleEventArgs arg)
    {
        // create a custom sorting rule
        NGroupingRule groupingRule = new NGroupingRule();
        NCustomRowValue<string> customRowValue = new NCustomRowValue<string>();
        customRowValue.GetRowValueDelegate = delegate(NCustomRowValueGetRowValueArgs<string> args)
        {
            DateTime received = Convert.ToDateTime(args.DataSource[args.Row, "Received"]);
            DateTime now = DateTime.Now;
            if (received.Year == now.Year && received.Month == now.Month && received.Day == now.Day)
            {
                return "Received Today";
            }
            else
            {
                return "Not Received Today";
            }
        };
        groupingRule.RowValue = customRowValue;
        // set that rule as event result
        arg.GroupingRule = groupingRule;
    };