Features > Data Grouping > Group Data using FlexGridGroupPanel > Custom Group Converters |
Besides providing support to group data on explicit columns, FlexGrid also supports creating custom group converters to group data based on some categories. For example, grouping data by some arbitrary order date or price point, or both can be vague. However, if the column price points can be further categorized into sub groups such as high, moderate, low, etc., then data organization becomes more meaningful. The FlexGridGroupPanel control enables users in realizing such grouping requirements by creating sub-groups or defining range.
The image given below illustrates custom data grouping on the basis of price range.
XAML |
Copy Code
|
---|---|
<Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition /> </Grid.RowDefinitions> <c1:C1FlexGridGroupPanel x:Name="_groupPanelCustomGrouping" Grid.Row="0" Background="WhiteSmoke" WatermarkText="Drag column headers here to create groups." MaxGroups="8" HideGroupedColumns="False" DragMarkerColor="#FF5C54" FlexGrid="{Binding ElementName=_flexCustomGrouping}" PropertyGroupCreated="_groupPanelCustomGrouping_PropertyGroupCreated"/> <c1:C1FlexGrid x:Name="_flexCustomGrouping" Grid.Row="1" TopLeftCellBackground="Bisque" ColumnHeaderBackground="Bisque" RowHeaderBackground="Bisque" GroupRowBackground="LightGoldenrodYellow" RowBackground="White" AlternatingRowBackground="White"/> </Grid> |
C# |
Copy Code
|
---|---|
public class Product : BaseObject { string _name, _color, _line; double _price, _cost; DateTime _date; bool _discontinued; static Random _rnd = new Random(); static string[] _names = "Macko|Surfair|Pocohey|Studeby".Split('|'); static string[] _lines = "Computers|Washers|Stoves|Cars".Split('|'); static string[] _colors = "Red|Green|Blue|White".Split('|'); public Product() { Name = PickOne(_names); Line = PickOne(_lines); Color = PickOne(_colors); Price = 30 + _rnd.NextDouble() * 1000; Cost = 3 + _rnd.NextDouble() * 300; Discontinued = _rnd.NextDouble() < .2; Introduced = DateTime.Today.AddDays(_rnd.Next(-600, 0)); } string PickOne(string[] options) { return options[_rnd.Next() % options.Length]; } //[Display(Name = "Name")] public string Name { get { return _name; } set { SetProperty("Name", ref _name, value); } } //[Display(Name = "Color")] public string Color { get { return _color; } set { SetProperty("Color", ref _color, value); } } //[Display(Name = "Line")] public string Line { get { return _line; } set { SetProperty("Line", ref _line, value); } } //[Display(Name = "Price")] public double Price { get { return _price; } set { SetProperty("Price", ref _price, value); } } //[Display(Name = "Cost")] public double Cost { get { return _cost; } set { SetProperty("Cost", ref _cost, value); } } //[Display(Name = "Introduced")] public DateTime Introduced { get { return _date; } set { SetProperty("Introduced", ref _date, value); } } //[Display(Name = "Discontinued")] public bool Discontinued { get { return _discontinued; } set { SetProperty("Discontinued", ref _discontinued, value); } } } public class BaseObject : INotifyPropertyChanged, IEditableObject { protected bool SetProperty<T>(string propName, ref T field, T value) { if (EqualityComparer<T>.Default.Equals(field, value)) return false; field = value; OnPropertyChanged(propName); return true; } public event PropertyChangedEventHandler PropertyChanged; void OnPropertyChanged(string propName) { OnPropertyChanged(new PropertyChangedEventArgs(propName)); } protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) { if (PropertyChanged != null) PropertyChanged(this, e); } object _clone = null; public void BeginEdit() { _clone = this.MemberwiseClone(); } public void CancelEdit() { foreach (var p in this.GetType().GetProperties()) { var value = p.GetValue(_clone, null); p.SetValue(this, value, null); } } public void EndEdit() { _clone = null; } } |
public class AmountGroupConverter : IValueConverter
{
double _maxValue;
public AmountGroupConverter(double maxValue)
{
_maxValue = maxValue;
}
public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
var pct = (double)value / _maxValue;
if (pct < .25) return "Very Low";
if (pct < .50) return "Low";
if (pct < .75) return "Moderate";
return "High";
}
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class DateTimeGroupConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
var list = new List<string>();
var date = (DateTime)value;
var today = DateTime.Today;
if (today.Subtract(date).TotalDays <= 7) list.Add("This week");
if (date.Year == today.Year && date.Month == today.Month) list.Add("This month");
if (date.Year == today.Year)
{
list.Add("This year");
}
else if (date.Year == today.Year - 1)
{
list.Add("Last year");
}
else
{
list.Add("Before last year");
}
return list;
}
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
C# |
Copy Code
|
---|---|
// create a data source var list = new List<Product>(); for (int i = 0; i < 200; i++) { list.Add(new Product()); } // assign the data source to grid var cvs = new CollectionViewSource() { Source = list }; _flexCustomGrouping.ItemsSource = cvs.View; |
C# |
Copy Code
|
---|---|
private void _groupPanelCustomGrouping_PropertyGroupCreated (object sender, C1.WPF.FlexGrid.PropertyGroupCreatedEventArgs e) { var pgd = e.PropertyGroupDescription; switch (pgd.PropertyName) { case "Introduced": pgd.Converter = new DateTimeGroupConverter(); break; case "Discontinued": pgd.Converter = new DateTimeGroupConverter(); break; case "Price": pgd.Converter = new AmountGroupConverter(1000); break; case "Cost": pgd.Converter = new AmountGroupConverter(300); break; } } |