Displaying summary data in an ASP.NET GridView
A recent project I worked on had the requirement of displaying a summary row for a GridView. Most of the approaches I came across had code that handled the GridView's RowDataBound event handler and then did the summary book keeping if the row being bound was a DataRow, and injected the summary value (total/max/min) if the row was a Footer. Similiar to the following
protected void ProductsInCategory_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { ... Increment the running totals ... } else if (e.Row.RowType == DataControlRowType.Footer) { ... Display the summary data in the footer ... } }
This appraoch works, but I thought it would be nice if this book-keeping logic could be factored out into its own component and specified via markup. I started playing around with implementing a prototype to see how it would work. Here was my basic approach:
- Create a GridView extension componenet that hooks into the RowDataBound event and does that essentailly what the code above does
- Allow for specifing the summary operation (Sum, Max, Min, Average ...) via markup
- Allow for formatting and styling via markup
I was looking for something similiar to the following ... Add the GridView to your page just as you would normally
<asp:GridView id="gvOrderDetails" runat="server" EnableViewState="false" DataSourceID="sqldsOrderDetails" AutoGenerateColumns="false" ShowFooter="true" > <Columns> <asp:BoundField HeaderText="Order ID" DataField="orderid" SortExpression="orderid" /> <asp:BoundField HeaderText="Product ID" DataField="productid" SortExpression="productid" /> <asp:BoundField HeaderText="Unit Price" DataField="unitprice" SortExpression="unitprice" /> <asp:BoundField HeaderText="Quantity" DataField="quantity" SortExpression="quantity" /> <asp:BoundField HeaderText="Discount" DataField="discount" SortExpression="discount" /> </Columns> </asp:GridView>
then add markup for the aggregate extension component as follows. Specifing which column indexes you would like aggregated, the operation you would like performed (Sum, Max, whatever) and possibly a few styling related items.
<mb:AggregateGridViewExtender ID="agveOrderDetails" runat="server" TargetControlID="gvOrderDetails"> <AggregateColumns> <mb:AggregateColumn ColumnIndex="2" Style-BackColor="red" DataField="unitprice" AggregateOperation="Sum" DataFormatString="Total: {0:C}" /> <mb:AggregateColumn ColumnIndex="3" Style-BackColor="orange" DataField="quantity" AggregateOperation="Max" DataFormatString="Max: {0}" /> </AggregateColumns> </mb:AggregateGridViewExtender>
I took a few hours and implemeted a prototype using the above approach. It is working but still needs some further investigation, testing and features. Anyway here is a sample screenshot, and a link (http://mattberseth.com/downloads/aggregate_gridview.zip) for the sample code. Feel free to let me know if you think this prototype is worth pursuing, or if the approach completly sucks.
Comments
this is a very good extender.
I think I can use it to improve a lot my gridviews.
why don't you submit it to ajaxcontroltoolkit features (even if it's not ajax).
lenyn76
This is certainly one of the better approaches I have came across. I think it would be more elegant if the syntax could be specified within the column instead of sepeartely though. That would get rid of the hard coded column numbers as well as the datafields.
why don't you add also the AVG operation?
this is the best summary approach I have seen.
-Please add an option to show the totals in the first row of a grid (since in long lists it is not comfortable to scroll down to see the total
-It would be better if you can add more explanations about the installation of your code