How to: Implement Custom Grouping
- 4 minutes to read
This example creates custom rules to group data. When you group data against the Unit Price column, this rule combines: rows that have values between 0 and 10 into a single group, rows that have values between 10 and 20 into another group, etc.
Note
A complete sample project is available at https://github.com/DevExpress-Examples/how-to-implement-custom-grouping-e1530.
<Window x:Class="DXGrid_CustomGrouping.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
Title="Window1" Height="300" Width="509">
<Grid>
<dxg:GridControl x:Name="grid"
CustomColumnGroup="grid_CustomColumnGroup"
CustomGroupDisplayText="grid_CustomGroupDisplayText"
ItemsSource="{Binding ListPerson}"
>
<dxg:GridControl.Columns>
<dxg:GridColumn FieldName="FirstName" />
<dxg:GridColumn FieldName="LastName" />
<dxg:GridColumn FieldName="UnitPrice" SortMode="Custom" GroupIndex="0">
<dxg:GridColumn.EditSettings>
<dxe:SpinEditSettings DisplayFormat="c2" />
</dxg:GridColumn.EditSettings>
</dxg:GridColumn>
</dxg:GridControl.Columns>
<dxg:GridControl.View>
<dxg:TableView AutoWidth="True" />
</dxg:GridControl.View>
</dxg:GridControl>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
namespace DXGrid_CustomGrouping {
public class MyViewModel {
public MyViewModel() {
CreateList();
}
public ObservableCollection<Person> ListPerson { get; set; }
void CreateList() {
ListPerson = new ObservableCollection<Person>();
for (int i = 0; i < 100; i++) {
Person p = new Person(i);
ListPerson.Add(p);
}
}
}
public class Person {
public Person() {
}
public Person(int i) {
FirstName = "FirstName" + i;
LastName = "LastName" + i;
UnitPrice = i ;
}
string _firstName;
public string FirstName {
get { return _firstName; }
set { _firstName = value; }
}
public string LastName { get; set; }
int _age;
public int UnitPrice {
get { return _age; }
set { _age = value; }
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections;
using DevExpress.Xpf.Grid;
namespace DXGrid_CustomGrouping {
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window {
public Window1() {
InitializeComponent();
this.DataContext = new MyViewModel();
}
private void grid_CustomColumnGroup(object sender,
CustomColumnSortEventArgs e) {
if (e.Column.FieldName == "UnitPrice") {
double x = Math.Floor(Convert.ToDouble(e.Value1) / 10);
double y = Math.Floor(Convert.ToDouble(e.Value2) / 10);
int res = Comparer.Default.Compare(x, y);
if (x > 9 && y > 9) res = 0;
e.Result = res;
e.Handled = true;
}
}
private void grid_CustomGroupDisplayText(object sender,
CustomGroupDisplayTextEventArgs e) {
if (e.Column.FieldName != "UnitPrice") return;
int groupLevel = grid.GetRowLevelByRowHandle(e.RowHandle);
if (groupLevel != e.Column.GroupIndex) return;
string interval = IntervalByValue(e.Value);
e.DisplayText = interval;
}
// Gets the text that represents the interval which contains the specified value.
private string IntervalByValue(object val) {
double d = Math.Floor(Convert.ToDouble(val) / 10);
string ret = string.Format("{0:c} - {1:c} ", d * 10, (d + 1) * 10);
if (d > 9) ret = string.Format(">= {0:c} ", 100);
return ret;
}
}
}