The DevExpress Grid (XtraGrid) allows grids and their groups to have summary calculations. The available options are Count, Max, Min, Avg, Sum, None and Custom.
Has anyone got some sample code that shows how to calculate a weighted average column, based upon the weightings provided as values in another column?
I ended up working this out, and will post my solution here in case others find it useful.
If a weighted average consists of both a value and a weight per row, then column that contains the value should have the weight GridColumn object assigned to its Tag property. Then, this event handler will do the rest:
private static void gridView_CustomSummaryCalculate(object sender, CustomSummaryEventArgs e)
{
GridColumn weightColumn = ((GridSummaryItem)e.Item).Tag as GridColumn;
if (weightColumn == null)
return;
switch (e.SummaryProcess)
{
case CustomSummaryProcess.Start:
{
e.TotalValue = new WeightedAverageCalculator();
break;
}
case CustomSummaryProcess.Calculate:
{
double size = Convert.ToDouble(e.FieldValue);
double weight = Convert.ToDouble(((GridView)sender).GetRowCellValue(e.RowHandle, weightColumn));
((WeightedAverageCalculator)e.TotalValue).Add(weight, size);
break;
}
case CustomSummaryProcess.Finalize:
{
e.TotalValue = ((WeightedAverageCalculator)e.TotalValue).Value;
break;
}
}
}
private sealed class WeightedAverageCalculator
{
private double _sumOfProducts;
private double _totalWeight;
public void Add(double weight, double size)
{
_sumOfProducts += weight * size;
_totalWeight += weight;
}
public double Value
{
get { return _totalWeight==0 ? 0 : _sumOfProducts / _totalWeight; }
}
}
The code assumes that the underlying column values can be converted to doubles via Convert.ToDouble(object)
.