FlexGrid for WPF | ComponentOne
Features / Data Grouping / Group Data using IDataCollection
In This Topic
    Group Data using IDataCollection
    In This Topic

    FlexGrid supports grouping through IDataCollection interface. This section discusses about grouping in FlexGrid .NET and .NET Framework versions using DataCollection.

    FlexGrid supports grouping through IDataCollection interface. You can create hierarchical views in FlexGrid by defining each level of grouping through the PropertyGroupDescription class. Using the PropertyGroupDescription object, you can select the property to group data, and implement ValueConverter to determine how to use property value while grouping.

    The following image shows data grouped by country and their active state. Users can click the icons on group headers to collapse or expand the groups, as they would do with a TreeView control.

    Grouping in FlexGrid

    The following code example illustrates data grouping by country and active state through DataCollection.

    XAML
    Copy Code
    List<Customer> list = GetCustomerList();
    PagedCollectionView view = new PagedCollectionView(list);
    using (view.DeferRefresh())
    {
      view.GroupDescriptions.Clear();
      view.GroupDescriptions.Add(new PropertyGroupDescription("Country"));
      view.GroupDescriptions.Add(new PropertyGroupDescription("Active"));
    }
    grid.ItemsSource = view;
    
    Note: The statement using (view.DeferRefresh()) is optional. It improves performance by suspending notifications from the data source until all the groups are set.

    To group data by country initials

    Besides grouping data by country column, you can implement grouping in FlexGrid as per various end-use requirement. For example, consider a custom scenario where data should be grouped by country initials in place of country column itself. The following image shows data grouped in FlexGrid through the first letter of the country name instead of complete country name.

    Grouping data by country initials

    To achieve this scenario through code, you need to create a custom class, CountryInitialConverter, that implements IValueConverter interface to return the first letter of the country name using the letter for grouping instead of the complete country name. In addition, you need to set the converter in MainWindow.xaml.cs as illustrated in the code examples given below.

    class CountryInitialConverter : IValueConverter
    {
      public object Convert(object value, Type targetType,
        object parameter,
        System.Globalization.CultureInfo culture)
      {
        return ((string)value)[0].ToString().ToUpper();
      }
      public object ConvertBack(object value, Type targetType,
        object parameter,
        System.Globalization.CultureInfo culture)
      {
        throw new NotImplementedException();
      }
    }
    
    List<Customer> list = GetCustomerList();
    PagedCollectionView view = new PagedCollectionView(list);
    using (view.DeferRefresh())
    {
      view.GroupDescriptions.Clear();
      view.GroupDescriptions.Add(new PropertyGroupDescription("Country"));
      view.GroupDescriptions.Add(new PropertyGroupDescription("Active"));
      var gd = view.GroupDescriptions[0] as PropertyGroupDescription;
      gd.Converter = new CountryInitialConverter();
    }
    grid.ItemsSource = view;
    

    Notice that the group rows display information about the groups they represent (the property and value being grouped on, and the item count). You can customize this information by creating a new IValueConverter class and assign it to the grid's GroupHeaderConverter property. For example, the default group header converter is implemented in the following code.

    C#
    Copy Code
    // class used to format group captions for display
    public class GroupHeaderConverter : IValueConverter
    {
      public object Convert(object value,
        Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
      {
        var gr = parameter as GroupRow;
        var group = gr.Group;
        if (group != null && gr != null && targetType == typeof(string))
        {
          var desc = gr.Grid.View.GroupDescriptions[gr.Level] as
                     PropertyGroupDescription;
          return desc != null
            ? string.Format("{0}: {1} ({2:n0} items)",
                     desc.PropertyName, group.Name, group.ItemCount)
            : string.Format("{0} ({1:n0} items)",
                     group.Name, group.ItemCount);
        }
        return value;
      }
      public object ConvertBack(object value, Type targetType,
        object parameter,
        System.Globalization.CultureInfo culture)
      {
        return value;
      }
    }
    
    FlexGrid supports grouping through IDataCollection interface. You can create hierarchical views in FlexGrid by defining each level of grouping through the PropertyGroupDescription class. Using the PropertyGroupDescription object, you can select the property to group data, and implement ValueConverter to determine how to use property value while grouping. You can also disable grouping by setting the grid's AllowGrouping property to False provided any column's AllowGrouping property is set to True.                

    The following image shows data grouped by country and their active state. Users can click the icons on group headers to collapse or expand the groups, as they would do with a TreeView control.

    DataGrouping

    The following code example illustrates data grouping by country and active state through DataCollection.

    C#
    Copy Code
    // Generate FlexGrid data
    var data = new ObservableCollection<Customer>();
    for (int i = 0; i < 200; i++)
    {
        data.Add(new Customer(i));
    }
    var view = new MyCollectionView(data);
    using (view.DeferRefresh())
    {
        view.GroupDescriptions.Clear();
        view.GroupDescriptions.Add(new PropertyGroupDescription("Country"));
        view.GroupDescriptions.Add(new PropertyGroupDescription("Active"));
        var gd = view.GroupDescriptions[0] as PropertyGroupDescription;                
    }
    
    // bind grids to ListCollectionView
    grid.ItemsSource = view;
    
    Note: The statement using (view.DeferRefresh()) is optional. It improves performance by suspending notifications from the data source until all the groups are set.

    To group data by country initials

    Besides grouping data by country column, you can implement grouping in FlexGrid as per various end-use requirement. For example, consider a custom scenario where data should be grouped by country initials in place of country column itself. The following image shows data grouped in FlexGrid through the first letter of the country name instead of complete country name.

    To achieve this scenario through code, you need to create a custom class, CountryInitialGrouping, that implements IValueConverter interface to return the first letter of the country name using the letter for grouping instead of the complete country name. In addition, you need to set the converter in MainWindow.xaml.cs as illustrated in the code examples given below.

    C#
    Copy Code
    public void CountryInitialGrouping()
    {
        // Generate FlexGrid data
        var data = new ObservableCollection<Customer>();
        for (int i = 0; i < 200; i++)
        {
            data.Add(new Customer(i));
        }
        var view = new MyCollectionView(data);
        using (view.DeferRefresh())
        {
            view.GroupDescriptions.Clear();
            view.GroupDescriptions.Add(new PropertyGroupDescription("Country"));
            view.GroupDescriptions.Add(new PropertyGroupDescription("Active"));
            var gd = view.GroupDescriptions[0] as PropertyGroupDescription;
            gd.Converter = new CountryInitialConverter();
        }
    
        //bind grids to ListCollectionView
        grid.ItemsSource = view;
    

    Notice that the group rows display information about the groups they represent (the property and value being grouped on, and the item count). You can customize this information by creating a new IValueConverter class and assign it to the grid's GroupHeaderConverter property. For example, the default group header converter is implemented in the following code.

    C#
    Copy Code
    // class used to format group captions for display
    public class GroupHeaderConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var group = parameter as GridGroupRow;
            var view = (MyCollectionView)group.Grid.ItemsSource;
            if (group != null && targetType == typeof(string))
            {
                var desc = view.GroupDescriptions[group.Level] as PropertyGroupDescription;
                return desc != null ? string.Format("{0}: {1} ({2:n0} items)", desc.PropertyName, group.GroupText, group.ItemsCount) : string.Format("{0} ({1:n0} items)", group.GroupText, group.ItemsCount);
            }
            return value;
        }
        public object ConvertBack(object value, Type targetType,
          object parameter,
          System.Globalization.CultureInfo culture)
        {
            return value;
        }
    
    See Also