Skip to main content Skip to footer

Add Dynamic Grouping to your WinForms Data Grid

The latest version of the FlexGrid control for WinForms adds a powerful and convenient feature -- dynamic grouping. Grouping can make data easier to understand, navigate, and analyze. Dynamic grouping automatically sorts the data, splits it into groups, and adds collapsible group rows above or below each group. The group rows may include aggregate values for one or more columns.

For example, consider this grid showing data from a DataTable object:

_flex.DataSource = myDataTable;

This will automatically generate columns and load the data to look like this:

Basic WinForms data grid

This is a typical grid view. You can inspect the data by sorting it and scrolling. You can even add some code to filter and aggregate the data.

You'll add grouping using the new GroupDescriptions property:

// bind grid to data source
_flex.DataSource = GetDataTable();

// add groups
_flex.GroupDescriptions = new GroupDescription[] {
    new GroupDescription("ShipCountry"),
    new GroupDescription("CategoryName")
};

// add aggregate to "Sale Amount" column
var col = _flexDataTable.Cols["Sale Amount"];
col.Aggregate = AggregateEnum.Sum;
col.Format = "N2";

// allow grouped cells to spill into empty cells
_flex.AllowMerging = AllowMergingEnum.Nodes;

Ther below grid is the result. The groups are collapsible, and the group header rows contain aggregate information for the Sale Amount column:

WinForms data grid group header rows

The grey rows represent group headers. They contain expand/collapse glyphs, a customizable string showing the group information (see the GroupHeaderFormat property), and aggregate information for any columns where the Aggregate property is set to a value other than None.

The Ship Country and Category Name columns contain a lot of repetitive data because the grid is grouped by those values. You can remove those columns from view automatically by setting the HideGroupedColumns property to true. The grid below does that and adds a little custom styling to the group rows:

Custom styling with grouped columns

Users can sort columns by clicking their headers with the mouse. Sorting grouped columns will sort the group values. Sorting ungrouped columns will sort values within each group only.

For example, if the user clicked the “Product Name” column header on the grid above, this will appear:

Sorting ungrouped columns

The groups have not changed, but the product names are now sorted alphabetically.

You can prevent mouse sorting by setting the AllowSorting property to false on the whole grid or on individual columns.

Sorting is an important part of grouping. To create and update the groups, the grid starts by performing a multi-property sort including all the groups plus any additional sorts created for example by user-clicks on column headers. After the data is sorted, the grid inserts the group header rows and calculates the subtotals as needed.

Because of this, grouping requires data sources that implement the IBindingListView interface. These include:

  1. The DataView class (used with data from databases),
  2. The SortableBindingList class included in the FlexGrid assembly (used with lists of custom objects), and
  3. Any other custom class that implements the IBindingListView interface.

Properties and classes that make up the FlexGrid’s dynamic grouping feature:

  1. Bind the grid by setting its DataSource property to a class that implements the IBindingListView interface (e.g. DataView or SortableBindingList).
  2. Set the grid’s GroupDescriptions property to a list of GroupDescription objects that describe how the data should be grouped.
  3. Optionally, set the grid’s GroupHeaderFormat property to define the content of the first cell in the group header rows.
  4. Optionally, set the grid’s AllowMerging property to AllowMergingEnum.Nodes so the group header content can spill into adjacent empty cells.
  5. Optionally, set the Aggregate property on columns to show their aggregate values (like sum or average) on the group header rows.
  6. Optionally, customize the appearance of the outline tree by setting the grid’s Tree.Style property (for example, set it to TreeStyleFlags.Leaf to show only the node text, without lines or collapse/expand glyphs).

GroupPanel

We also added a GroupPanel control to enable run time grouping in FlexGrid. This feature is built upon the dynamic grouping discussed above. You can drag column headers into the panel to create groups and drag groups to new positions. In addition, you can use the context menu to collapse all, expand all, and clear grouping.

The GroupPanel also allows you to limit the maximum number of groups that can be created (through the MaxGroups property) and to determine whether grouped columns should be displayed on the grid (through the HideGroupedColumns property).

Grouping panels in WinForms data grid

How to add a Group Panel to FlexGrid
  1. Drag and drop the GroupPanel control from toolbox on the form, place it above FlexGrid,
  2. Set the FlexGrid property ofGroupPanel to instance of FlexGrid on the form.
  3. Optionally, set the Text property like “Drag a column here to group by that column.”
  4. Optionally, set MaxGroups property to limit the number of groups allowed.
  5. Optionally, set the HideGroupedColumns property to show\hide grouped columns in grid.

We hope you like the new dynamic grouping feature. We think it is very useful and easy to use. It also improves compatibility between the FlexGrid implementations available on platforms including WPF and JavaScript.

Bernardo de Castilho

comments powered by Disqus