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.

<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;
        }

    }
}