KB Article A2346
Visible to All Users

A better way to implement a frequently used custom summary (Weighted Averages example)

Description:
I need to implement weighted average summaries for a lot of the grids in my application. I know that this can be accomplished by handling the CustomSummaryCalculate event. However, the formula is quite complex and the event handler is large and so it's difficult to maintain it. Will you make the weighted average summary a built-in function of the XtraGrid?

Answer:
Grid summaries are calculated for a single data column. Weighted averages depend upon the values in two columns. It may be difficult for us to redesign summation algorithms for multi-column formulas.
We can suggest a solution so you can easily include a custom summary function in all grids. You can move the summary formula out of the CustomSummaryCalculate event handler, so that a result is calculated in a separate function, which can be shared by several grids.

C#
using DevExpress.XtraGrid.Columns; using DevExpress.XtraGrid.Views.Grid; public static object GetWeightedAverage(GridView view, string weightField, string valueField) { const decimal undefined = 0; if(view == null) return undefined; GridColumn weightCol = view.Columns[weightField]; GridColumn valueCol = view.Columns[valueField]; if(weightCol == null || valueCol == null) return undefined; try { decimal totalWeight = 0, totalValue = 0; for(int i = 0; i < view.DataRowCount; i++) { if(view.IsNewItemRow(i)) continue; object temp; decimal weight, val; temp = view.GetRowCellValue(i, weightCol); weight = (temp == DBNull.Value || temp == null) ? 0 : Convert.ToDecimal(temp); temp = view.GetRowCellValue(i, valueCol); val = (temp == DBNull.Value || temp == null) ? 0 : Convert.ToDecimal(temp); totalWeight += weight; totalValue += weight * val; } if(totalWeight == 0) return undefined; return totalValue / totalWeight; } catch { return undefined; } }

You still need to handle the CustomSummaryCalculate event, but just check that the e.SummaryProcess is equal to CustomSummaryProcess.Finalize and assign the summary result to the e.TotalValue parameter.

C#
private void gridView1_CustomSummaryCalculate(object sender, DevExpress.Data.CustomSummaryEventArgs e) { if(e.IsTotalSummary && e.SummaryProcess == CustomSummaryProcess.Finalize) { GridView view = sender as GridView; if(e.Item == view.Columns["UnitPrice"].SummaryItem) { e.TotalValue = CustomSummaryHelper.GetWeightedAverage(view, "Quantity", "UnitPrice"); } } }

See Also:

Comments (2)

    last row, no calcurate ???

    DevExpress Support Team 12 years ago

      Hi,
      I'm afraid that the issue is not quite clear to me. The following cycle traverses through all grid rows, because the grid row handles start from 0:

      C#
      for(int i = 0; view.DataRowCount; i++)

      I have also checked a project from the A better way to implement a frequently used custom summary (Weighted Averages example) example. It operates as expected. I have attached this project to your reference.
      If the issue persists, please describe in greater detail what is wrong in our example and we will research this issue on our side. We are looking forward to your response.

      Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

      Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.