Working with Groups in Code
- 9 minutes to read
Group and Ungroup Data
Groups data against this column. If data is already grouped by other columns, this column will be added to the end of the grouping queue.
Removes data grouping by this column.
Removes all data grouping.
Accepts non-negative integer values that specify the column order according to which data is grouped. Values must be unique, which means you cannot apply merged column grouping by setting column group indexes. You can change this property only for columns that have already been added to a View.
A collection that stores specific ColumnSortInfo objects on every grid column involved in sorting and grouping. To apply complex grouping in code, modify this collection manually by calling the GridColumnSortInfoCollection.ClearAndAddRange method. The code below applies two grouping layers: merged grouping by “Ship Country”, “Ship City” and “Ship Region” columns, followed by tier two grouping by the “Customer ID” column.
gridView1.SortInfo.ClearAndAddRange(new[] {
new GridMergedColumnSortInfo(
new[] {
colShipCountry, colShipCity, colShipRegion},
new[] {
ColumnSortOrder.Ascending, ColumnSortOrder.Descending, ColumnSortOrder.Ascending }),
new GridColumnSortInfo(colCustomerID, ColumnSortOrder.Descending)
}, 4);
ColumnView.StartGrouping, ColumnView.EndGrouping
Non-cancelable events that fire whenever a grouping operation takes place.
Modify Group Row Content
GridView.GroupFormat, GridColumn.GroupFormat
Allows you to modify group row content for individual Grid columns, or all columns at once.
GridView.CustomDrawGroupRow, GridView.CustomColumnDisplayText
Allows you to modify specific group row captions.
colShipCountry.GroupInterval = DevExpress.XtraGrid.ColumnGroupInterval.Alphabetical;
private void gridView1_CustomDrawGroupRow(object sender, DevExpress.XtraGrid.Views.Base.RowObjectCustomDrawEventArgs e) {
GridGroupRowInfo info = e.Info as GridGroupRowInfo;
if (info.Column == colShipCountry) {
info.GroupText = "Ship country starts with " + info.GroupValueText;
}
}
GridOptionsBehavior.AlignGroupSummaryInGroupRow
Allows you to display group summaries within group rows.
Custom Grouping
Set this property to Custom to implement custom grouping.
Fires for all columns with the custom sort mode when grid data is grouped against these columns. Allows you to implement custom grouping algorithms.
ColumnView.CustomColumnDisplayText or GridView.CustomDrawGroupRow
Handle any of these events to modify group row captions accordingly to your custom grouping algorithms. The sample below illustrates how to break order dates into four seasons and group orders by these seasons.
using System;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using System.Collections.Generic;
using DevExpress.XtraGrid.Columns;
namespace CustomGroupingSample {
public partial class XtraForm1 : DevExpress.XtraEditors.XtraForm {
public XtraForm1() {
InitializeComponent();
// This line of code is generated by Data Source Configuration Wizard
ordersTableAdapter1.Fill(_Northwind2010___CopyDataSet11.Orders);
gridView1.OptionsView.ShowGroupedColumns = true;
gridView1.SortInfo.ClearAndAddRange(new[] {
new GridColumnSortInfo(colOrderDate, DevExpress.Data.ColumnSortOrder.Ascending)
});
colOrderDate.SortMode = DevExpress.XtraGrid.ColumnSortMode.Custom;
gridView1.CustomColumnGroup += GridView1_CustomColumnGroup;
gridView1.CustomColumnDisplayText += GridView1_CustomColumnDisplayText;
//or
gridView1.CustomDrawGroupRow += GridView1_CustomDrawGroupRow;
}
//Custom Grouping
private void GridView1_CustomColumnGroup(object sender, CustomColumnSortEventArgs e) {
if (e.Column == colOrderDate) {
DateTime value1 = (DateTime)e.Value1;
DateTime value2 = (DateTime)e.Value2;
if (GetSeason(value1) == GetSeason(value2)) e.Result = 0;
else e.Result = 1;
e.Handled = true;
}
}
//Get season by date
private string GetSeason(DateTime date) {
Int32 month = date.Month;
string season = "Winter";
if (month == 3 || month == 4 || month == 5) season = "Spring";
if (month == 6 || month == 7 || month == 8) season = "Summer";
if (month == 9 || month == 10 || month == 11) season = "Fall";
return season;
}
//Custom group row content (option #1)
private void GridView1_CustomColumnDisplayText(object sender, CustomColumnDisplayTextEventArgs e) {
GridView view = sender as GridView;
if (view == null) return;
if (e.Column == colOrderDate && e.IsForGroupRow) {
DateTime rowValue = (DateTime)view.GetGroupRowValue(e.GroupRowHandle, e.Column);
string season = GetSeason(rowValue);
if (season != "Winter") e.DisplayText = season + " " + rowValue.Year;
else e.DisplayText = season + " " + rowValue.Year + "/" + rowValue.AddYears(1).Year;
}
}
//Custom group row content (option #2)
private void GridView1_CustomDrawGroupRow(object sender, DevExpress.XtraGrid.Views.Base.RowObjectCustomDrawEventArgs e) {
GridGroupRowInfo info = e.Info as GridGroupRowInfo;
GridView view = sender as GridView;
if (info.Column == colOrderDate) {
DateTime rowValue = (DateTime)view.GetGroupRowValue(info.RowHandle, info.Column);
string season = GetSeason(rowValue);
if (season != "Winter") info.GroupText = "Order Date: " + season + " " + rowValue.Year;
else info.GroupText = "Order Date: " + season + " " + rowValue.Year + "/" + rowValue.AddYears(1).Year;
}
}
}
}
Locate and Process Group Rows
Row handles are integer values that identify both data (positive values) and group (negative values) rows.
Identifies the nesting level of a row.
Returns the number of immediate child rows for a group row.
Returns the row handle of a group row’s child data row. The following example shows how to change the “Price” column value for all the data rows belonging to the focused data group. Prices change when end-users press the “Discount” button.
using DevExpress.XtraGrid.Views.Grid;
//...
private void buttonDiscount_Click(object sender, System.EventArgs e) {
GridView view = gridView1;
int rowHandle = view.FocusedRowHandle;
ArrayList rowsToDiscount = new ArrayList();
//Get related data rows
if(view.IsGroupRow(rowHandle))
getChildRows(view, rowHandle, rowsToDiscount);
//Change the values of the rows
view.BeginUpdate();
discount(rowsToDiscount);
view.EndUpdate();
}
//Returns the child data rows for the given group row
public void getChildRows(GridView view, int groupRowHandle, ArrayList childRows) {
if(!view.IsGroupRow(groupRowHandle)) return;
//Get the number of immediate children
int childCount = view.GetChildRowCount(groupRowHandle);
for(int i=0; i<childCount; i++){
//Get the handle of a child row with the required index
int childHandle = view.GetChildRowHandle(groupRowHandle, i);
//If the child is a group row, then add its children to the list
if(view.IsGroupRow(childHandle))
getChildRows(view, childHandle, childRows);
else {
// The child is a data row.
// Add it to the childRows as long as the row wasn't added before
object row = view.GetRow(childHandle);
if(!childRows.Contains(row))
childRows.Add(row);
}
}
}
//Changes the values of the Price column for the specified rows
public void discount(ArrayList rows) {
for(int i = 0; i < rows.Count; i++) {
DataRow row = (rows[i] as DataRowView).Row;
decimal oldValue = (decimal)row["Price"];
row["Price"] = oldValue * 0.95m;
}
}
Returns the row handle of a parent row.
ColumnView.GetRow/ColumnView.GetDataRow
Methods that retrieve System.Data.DataRowView or other objects, which represent data source rows.
Expand and Collapse Rows
Returns whether or not the row is expanded.
GridView.ExpandGroupRow/GridView.CollapseGroupRow
Call this method to expand or collapse a row.
Expands or collapses a row itself and (optionally) all of its child rows.
GridView.GroupRowExpanding/GridView.GroupRowCollapsing
Cancelable events that fire when a group is to be expanded or collapsed.
GridView.GroupRowExpanded/GridView.GroupRowCollapsed
These events occur after a row has been expanded or collapsed.
Scrolls the View to display the required row and selects this row. Expands the row’s parent group.
Scrolls the View to display the required row. If the row belongs to a group, this group expands. The code snippet below displays all rows whose “InStock” column values equal false.
using DevExpress.XtraGrid.Views.Grid;
//...
GridView View = gridView1;
int rowHandle = -1;
do {
rowHandle = View.LocateByValue(rowHandle+1, View.Columns["Is In Stock"], false);
View.MakeRowVisible(rowHandle, false);
} while(rowHandle != GridControl.InvalidRowHandle);