Description: The drilldown report displays customer shipped order information. Users are presented with a list of customers. From there, they can click on a customer and see the orders shipped to that customer. Furthermore, they can click on an order ID to view the details for that particular order.
Overview: The drilldown report shows a way of displaying a hierarchy of data, in this instance customers --> orders --> order details.
Implementation Notes: The list of customers is a Datalist. Inside of the selected template for the Customers Datalist is the Orders Datalist. And inside of the Orders Datalist's selected template is the Order Details Datagrid. The selected template determines the content and layout of the selected item of datalist.
The Datalist is used for the customers and orders list because of its selected template feature. The Datagrid is used to easily display the Order details since it does not require a selected template.
<asp:datalist id="CustomerList" runat="server" ... >
...
<selecteditemtemplate>
<asp:datalist id="OrderList" runat="server" DataSource='<%# GetOrders(DataBinder.Eval(Container.DataItem, "CustomerID")) %>' >
...
<selecteditemtemplate>
<asp:datagrid id=OrderDetailsGrid runat="server" DataSource='<%# GetOrderDetails(CInt(DataBinder.Eval(Container.DataItem, "OrderID"))) %>' >
<columns>
<asp:boundcolumn DataField="ProductName" HeaderText="Product" ... ></asp:boundcolumn>
<asp:boundcolumn DataField="UnitPrice" HeaderText="Unit Price" DataFormatString="{0:c}" ... ></asp:boundcolumn>
<asp:boundcolumn DataField="Quantity" HeaderText="Quantity" ... ></asp:boundcolumn>
</columns>
</asp:datagrid>
</selecteditemtemplate>
</asp:datalist>
</selecteditemtemplate>
</asp:datalist>
To show the selected itemtemplate, an event is added to the CustomerList. An event handler is also added to the OrdersList. The event handler looks to see if a "select" command is called and sets the selected index of the corresponding Datalist and then re-binds the Datalist.
<asp:datalist id="CustomerList" runat="server" ... OnItemCommand="DataList_ItemCommand" >
...
<itemtemplate>
<asp:linkbutton id="button1" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "CompanyName") %>' CommandName="select" />
</itemtemplate>
<selecteditemtemplate>
<asp:datalist id="OrderList" runat="server" OnItemCommand="OrdersList_ItemCommand" %>' >
...
<itemtemplate>
<asp:linkbutton id="Linkbutton1" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "OrderID") %>' CommandName="select" />
</itemtemplate>
<selecteditemtemplate>
<asp:datagrid id=OrderDetailsGrid runat="server" ... %>' >
<columns>
<asp:boundcolumn DataField="ProductName" HeaderText="Product" ... ></asp:boundcolumn>
<asp:boundcolumn DataField="UnitPrice" HeaderText="Unit Price" DataFormatString="{0:c}" ... ></asp:boundcolumn>
<asp:boundcolumn DataField="Quantity" HeaderText="Quantity" ... ></asp:boundcolumn>
</columns>
</asp:datagrid>
</selecteditemtemplate>
</asp:datalist>
</selecteditemtemplate>
</asp:datalist>
Since the Orders Datalist is inside of the Customers Datalist's selected template, it is dynamically generated as the Customers Datalist is data binding. The Customers Datalist passes in the customer ID of the selected customer to the Orders Datalist. The Orders DataList then binds to the orders for that selected customer.
The customer ID is placed in a hidden label control so that it can be retrieve in the OnItemCommand event of the Customers Datalist.
<asp:label id="CustomerID" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "CustomerID") %>' Visible=False />
The customer ID is saved in ViewState in the OnItemCommand event of the Customers Datalist. The customer ID must be saved so that when the Orderlist selected index changes, it can re-bind to the correct customer. It is retrieved when the page is posted back and the OnItemCommand event is raised for the Orders Datalist.
'*******************************************************
'
' DataList_ItemCommand event handler is tied to the OnItemDataBound of the Customers DataList.
' It sets the selected index of the Customers List and then re-binds.
'
'*******************************************************
Protected Sub CustomersList_ItemCommand(ByVal Sender As Object, ByVal e As DataListCommandEventArgs)
' change the Datalist to selected index
Dim cmd As String = CType(e.CommandSource, LinkButton).CommandName
If cmd = "select" Then
CType(Sender, DataList).SelectedIndex = e.Item.ItemIndex
End If
' re-bind to display data with the new selected index
BindList()
' store the customer id to re-bind in the orders list
ViewState(_customerID) = CType(e.Item.FindControl("CustomerID"), Label).Text
End Sub 'CustomersList_ItemCommand
Protected Sub OrdersList_ItemCommand(ByVal Sender As Object, ByVal e As DataListCommandEventArgs)
' change the selected index of Orders Datalist
Dim cmd As String = CType(e.CommandSource, LinkButton).CommandName
Dim senderlist As DataList = CType(Sender, DataList)
If cmd = "select" Then
senderlist.SelectedIndex = e.Item.ItemIndex
End If
' re-bind to display orders info with new selected index.
senderlist.DataSource = GetOrders(CStr(ViewState(_customerID)))
senderlist.DataBind()
End Sub 'OrdersList_ItemCommand