J'ai fini par mettre cela au point, et je posterai ma solution ici au cas où d'autres la trouveraient utile.
Si une moyenne pondérée comprend à la fois une valeur et un poids par ligne, la colonne contenant la valeur doit avoir l'objet GridColumn de poids affecté à sa propriété Tag. Ensuite, ce gestionnaire d'événements fera le reste:
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; }
}
}
Le code suppose que les valeurs des colonnes sous-jacentes peuvent être convertis en double via Convert.ToDouble(object)
.
@MBirchmeier, merci pour la réponse mais celle-ci ne s'intégrera pas à l'API de contrôle de grille. –
Désolé ce matin tôt je pensais que LINQ pourrait être utilisé comme source de données sans prendre la peine de vérifier cela. J'imagine que vous devez utiliser la fonction 'custom', mais je ne trouve aucune documentation dessus. – MBirchmeier