Description: The tabular report displays a list of products grouped by product category.
Overview: The tabular report shows a basic way of grouping related data (in this case, grouping products by category). The grouping is done by nesting a DataGrid control inside of a DataList control.
Additionally, this report demonstrates how to implement interactive sorting using the DataGrid Server Control.
For this report, sorting is enabled for each column in the Product Details header, except for the Quantity per Unit and Extended Price columns. The sortable columns can be sorted in ascending or descending order. Sortable columns are displayed as red and underlined when the user hovers over the column header.
In addition to sorting, the DataGrid also features the ability to selectively control the formatting of a row based on custom criteria. In this case, Products which are out of stock (designated with a quantity of zero) will be displayed inred.
The extended price is calculated as the Datagrid is data binding. It is displayed as the right most column.
Implementation Notes: To group the related data, a DataGrid control is nested inside of a DataList control. In this case, DataGrid is chosen for it's ability to implement sorting and to examine its data source during runtime.
The above diagram shows how the DataList and the DataGrid work in tandem. The DataList displays the category name and summary information, while the DataGrid returns the products details based on the Category ID passed in from the DataList for each category.
The DataList's data source is a TabularReportCollection returned from the GetHeader function. To correlate each category with its details, the DataGrid's data source is assigned dynamically by calling the GetDetails function for each category as the DataList is binding.
<asp:datagrid id=Datagrid1 runat="server" DataSource='<%# GetDetails(DataBinder.Eval(Container.DataItem, "CategoryID") %>' ... >
Sorting is a simple task to implement with ASP.NET. The DataGrid's AllowSorting property is set to True and an event handler for the sorting is added to the DataGrid. The event handler then catches the sorting criteria where it is used to sort the appropriate DataGrid column.
<asp:datagrid id=Datagrid1 runat="server" ... AllowSorting="true" OnSortCommand="SortGrid">
Private Sub SortGridData(ByVal list As TabularReportCollection, ByVal sortField As String, ByVal asc As Boolean)
Dim sortCol As TabularReportCollection.TabularReportFields = TabularReportCollection.TabularReportFields.InitValue
Select Case sortField
Case "ProductName"
sortCol = TabularReportCollection.TabularReportFields.ProductName
Case "UnitPrice"
sortCol = TabularReportCollection.TabularReportFields.UnitPrice
Case "UnitsInStock"
sortCol = TabularReportCollection.TabularReportFields.UnitsInStock
End Select
list.Sort(sortCol, asc)
End Sub 'SortGridData
Public Overloads Sub Sort(ByVal sortField As TabularReportFields, ByVal isAscending As Boolean)
Select Case sortField
Case TabularReportFields.ProductName
MyBase.Sort(New ProductNameComparer())
Case TabularReportFields.UnitsInStock
MyBase.Sort(New UnitsInStockComparer())
Case TabularReportFields.UnitPrice
MyBase.Sort(New UnitPriceComparer())
End Select
If Not isAscending Then
MyBase.Reverse()
End If
End Sub 'Sort
The color coding is done by checking the units in stock as the inner DataGrid databind and changing the style class for that line item.
' if there are no units in stock, color the line item as red by changing the style class
If unitsInStock = 0 Then
e.Item.CssClass = "OutOfStock"
End If
The OutOfStock style used above is defined in the styles.css file.
.OutOfStock
{
color: red;
}
To calculate the extended, an event handler is added to the OnItemDataBound event of the Datagrid. It retrieves the unit price and multiplies that to the units in stock to calculate the extended price of a product.
Protected Sub CalculateExtendedPrice(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs)
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
Dim unitsInStock As Double = Convert.ToDouble(e.Item.Cells(1).Text)
Dim unitPrice As Double = Convert.ToDouble(e.Item.Cells(4).Text)
e.Item.Cells(5).Text = String.Format("{0:c}", unitPrice * unitsInStock)
' format unit price column as currency
e.Item.Cells(4).Text = String.Format("{0:c}", unitPrice)
' if there are no units in stock, color the line item as red by changing the style class
If unitsInStock = 0 Then
e.Item.CssClass = "OutOfStock"
End If
End If
End Sub 'CalculateExtendedPrice