Tutorial 33: Master/Detail Filtering with a DropDownList
Scot Mitchell
May 2007
Summary: This is the Visual C# tutorial. (Switch to the Visual Basic tutorial) In this tutorial, we see how to display master/detail reports in a single web page using DropDownLists to display the "master" records and a DataList to display the "details."
Download the code for this sample
Contents
Introduction
Step 1. Adding the Master/Detail Tutorial Web Pages
Step 2: Displaying the Categories in a DropDownList
Step 3: Adding the Products DataList
Adding a "-- Choose a Category --" List Item
Summary
Introduction
The master/detail report, which we first created using a GridView in Tutorial 7: Master/Detail Filtering With a DropDownList, begins by showing some set of "master" records. The user can then drill down into one of the master records, thereby viewing that master record "details." Master/detail reports are an ideal choice for visualizing one-to-many relationships and for displaying detailed information from particularly "wide" tables (ones that have a lot of columns). We've explored how to implement master/detail reports using the GridView and DetailsView controls in previous tutorials. In this tutorial and the next two, we'll reexamine these concepts, but focus on using DataList and Repeater controls instead.
In this tutorial, we'll look at using a DropDownList
to contain the "master" records, with the "details" records displayed in a DataList
.
Step 1. Adding the Master/Detail Tutorial Web Pages
Before we start this tutorial, let's first take a moment to add the folder and ASP.NET pages we'll need for this tutorial and the next two dealing with master/detail reports using the DataList and Repeater controls. Start by creating a new folder in the project named DataListRepeaterFiltering. Next, add the following five ASP.NET pages to this folder, configuring all of them to use the master page Site.master:
- Default.aspx
- FilterByDropDownList.aspx
- CategoryListMaster.aspx
- ProductsForCategoryDetails.aspx
- CategoriesAndProducts.aspx
Figure 1. Create a DataListRepeaterFiltering folder and add the tutorial ASP.NET pages
Next, open the Default.aspx page and drag the SectionLevelTutorialListing.ascx User Control from the UserControls folder onto the Design surface. This User Control, which we created in Tutorial 3: Master Pages and Site Navigation, enumerates the site map and displays the tutorials from the current section in a bulleted list.
Figure 2. Add the SectionLevelTutorialListing.ascx User Control to Default.aspx
In order to have the bulleted list display the master/detail tutorials we'll be creating, we need to add them to the site map. Open the Web.sitemap file and add the following markup after the "Displaying Data with the DataList and Repeater" site map node markup:
<siteMapNode title="Master/Detail Reports with the DataList and Repeater" description="Samples of Reports that Use the DataList and Repeater Controls" url="~/DataListRepeaterFiltering/Default.aspx"> <siteMapNode title="Filter by Drop-Down List" description="Filter results using a drop-down list." url="~/DataListRepeaterFiltering/FilterByDropDownList.aspx" /> <siteMapNode title="Master/Detail Across Two Pages" description="Master records on one page, detail records on another." url="~/DataListRepeaterFiltering/CategoryListMaster.aspx" /> <siteMapNode title="Maser/Detail on One Page" description="Master records in the left column, details on the right, both on the same page." url="~/DataListRepeaterFiltering/CategoriesAndProducts.aspx" /> </siteMapNode>
Figure 3. Update the site map to include the new ASP.NET pages
Step 2: Displaying the Categories in a DropDownList
Our master/detail report will list the categories in a DropDownList, with the selected list items products displayed further down in the page in a DataList. The first task ahead of us, then, is to have the categories displayed in a DropDownList. Start by opening the FilterByDropDownList.aspx page in the DataListRepeaterFiltering folder and drag a DropDownList from the Toolbox onto the page designer. Next, set the DropDownList ID property to Categories. Click on the Choose Data Source link from the DropDownList smart tag and create a new ObjectDataSource named CategoriesDataSource.
Figure 4. Add a new ObjectDataSource named "CategoriesDataSource"
Configure the new ObjectDataSource
such that it invokes the CategoriesBLL
class GetCategories()
method. After configuring the ObjectDataSource
we still need to specify what data source field should be displayed in the DropDownList
and which one should be associated as the value for each list item. Have the CategoryName
field as the display and CategoryID
as the value for each list item.
Figure 5. Have the DropDownList display the CategoryName field and use CategoryID as the value
At this point, we have a DropDownList control that's populated with the records from the Categories table (all accomplished in about six seconds). Figure 6 shows our progress thus far when viewed through a browser.
Figure 6. A Drop-Down Lists the Current Categories
Step 3: Adding the Products DataList
The last step in our master/detail report is to list the products associated with the selected category. To accomplish this, add a DataList to the page and create a new ObjectDataSource
named ProductsByCategoryDataSource
. Have the ProductsByCategoryDataSource
control retrieve its data from the ProductsBLL
class GetProductsByCategoryID(categoryID)
method. Since this master/detail report is read-only, choose the (None) option in the INSERT, UPDATE, and DELETE tabs.
Figure 7. Select the GetProductsByCategoryID(categoryID) method
After clicking Next, the ObjectDataSource
wizard prompts us for the source of the value for the GetProductsByCategoryID(categoryID)
methods categoryID
parameter. To use the value of the selected categories DropDownList item set the Parameter
source to Control
and the ControlID
to Categories
.
Figure 8. Set the categoryID parameter to the value of the categories DropDownList
Upon completing the Configure Data Source wizard, Visual Studio will automatically generate an ItemTemplate
for the DataList that displays the name and value of each data field. Let's enhance the DataList to instead use an ItemTemplate
that displays just the product name, category, supplier, quantity per unit, and price along with a SeparatorTemplate
that injects an <hr>
element between each item. I'm going to use the ItemTemplate
from an example in Tutorial 29: Displaying Data with the DataList and Repeater Controls, but feel free to use whatever template markup you find most visually appealing.
After making these changes, your DataList and its ObjectDataSource markup should look similar to the following:
<asp:DataList ID="DataList1" runat="server" DataKeyField="ProductID" DataSourceID="ProductsByCategoryDataSource" EnableViewState="False"> <ItemTemplate> <h4> <asp:Label ID="ProductNameLabel" runat="server" Text='<%# Eval("ProductName") %>' /> </h4> <table border="0"> <tr> <td class="ProductPropertyLabel">Category:</td> <td><asp:Label ID="CategoryNameLabel" runat="server" Text='<%# Eval("CategoryName") %>' /></td> <td class="ProductPropertyLabel">Supplier:</td> <td><asp:Label ID="SupplierNameLabel" runat="server" Text='<%# Eval("SupplierName") %>' /></td> </tr> <tr> <td class="ProductPropertyLabel">Qty/Unit:</td> <td><asp:Label ID="QuantityPerUnitLabel" runat="server" Text='<%# Eval("QuantityPerUnit") %>' /></td> <td class="ProductPropertyLabel">Price:</td> <td><asp:Label ID="UnitPriceLabel" runat="server" Text='<%# Eval("UnitPrice", "{0:C}") %>' /></td> </tr> </table> </ItemTemplate> <SeparatorTemplate> <hr /> </SeparatorTemplate> </asp:DataList> <asp:ObjectDataSource ID="ProductsByCategoryDataSource" runat="server" OldValuesParameterFormatString="original_{0}" SelectMethod="GetProductsByCategoryID" TypeName="ProductsBLL"> <SelectParameters> <asp:ControlParameter ControlID="Categories" Name="categoryID" PropertyName="SelectedValue" Type="Int32" /> </SelectParameters> </asp:ObjectDataSource>
Take a moment to check out our progress in a browser. When first visiting the page, those products belonging to the selected category (Beverages) are displayed (as shown in Figure 9), but changing the DropDownList doesn't update the data. This is because a postback must occur for the DataList to update. To accomplish this we can either set the AutoPostBack
DropDownList property to true
or add a Button Web control to the page. For this tutorial, I've opted to set the AutoPostBack
DropDownList property to true
.
Figures 9 and 10 illustrate the master/detail report in action.
Figure 9. When first visiting the page, the beverage products are displayed
Figure 10. Selecting a new product (Produce) automatically causes a PostBack, updating the DataList
Adding a "-- Choose a Category --" List Item
When first visiting the FilterByDropDownList.aspx page the categories DropDownList first list item (Beverages) is selected by default, showing the beverage products in the DataList. In Tutorial 7: Master/Detail Filtering With a DropDownList, we added a "-- Choose a Category --" option to the DropDownList that was selected by default, and when selected displayed all products in the database. Such an approach was manageable when listing the products in a GridView, as each product row took a small amount of screen real estate. With the DataList, however, the information for each product consumes a much larger chunk of the screen. Let's still add a "-- Choose a Category --" option and have it selected by default. But instead of having it show all products when selected, let's configure it so that it shows no products.
To add a new list item to the DropDownList, go to the Properties window and click on the ellipses in the Items property. Add a new list item with the Text "-- Choose a Category --" and the Value 0.
Figure 11. Add a "-- Choose a Category --" list item
Alternatively, you can add the list item by adding the following markup to the DropDownList:
<asp:DropDownList ID="categories" runat="server" AutoPostBack="True" DataSourceID="CategoriesDataSource" DataTextField="CategoryName" DataValueField="CategoryID" EnableViewState="False"> <asp:ListItem Value="0">-- Choose a Category --</asp:ListItem> </asp:DropDownList>
Additionally, we need to set the AppendDataBoundItems
DropDownList control to true
because if it's set to false
(the default), when the categories are bound to the DropDownList from the ObjectDataSource
they'll overwrite any manually-added list items.
Figure 12. Set the AppendDataBoundItems property to "True"
The reason we chose the value 0
for the "-- Choose a Category --" list item is because there are no categories in the system with a value of 0
, hence no product records will be returned when the "-- Choose a Category --" list item is selected. To confirm this, take a moment to visit the page through a browser. As Figure 13 shows, when initially viewing the page the "-- Choose a Category --" list item is selected and no products are displayed.
Figure 13. When the "-- Choose a Category --" list item is selected, no products are displayed
If you'd rather display all of the products when the "-- Choose a Category --" option is selected, use a value of -1
instead. The astute reader will recall that back in the Master/Detail Filtering With a DropDownList tutorial we updated the GetProductsByCategoryID(categoryID)
ProductsBLL
class method so that if a categoryID
value of -1
was passed in, all product records were returned.
Summary
When displaying hierarchically-related data, it often helps to present the data using master/detail reports, from which the user can start perusing the data from the top of the hierarchy and drill down into details. In this tutorial we examined building a simple master/detail report showing a selected category products. This was accomplished by using a DropDownList for the list of categories and a DataList for the products belonging to the selected category.
In the next tutorial we'll look at separating the master and details records across two pages. In the first page, a list of "master" records will be displayed, with a link to view the details. Clicking on the link will whisk the user to the second page, which will display the details for the selected master record.
Happy Programming!
About the Author
Scott Mitchell, author of seven ASP/ASP.NET books and founder of 4GuysFromRolla.com, has been working with Microsoft Web technologies since 1998. Scott works as an independent consultant, trainer, and writer. His latest book is Sams Teach Yourself ASP.NET 2.0 in 24 Hours. He can be reached at mitchell@4GuysFromRolla.com, or via his blog http://ScottOnWriting.NET.
Acknowledgements
This tutorial series was reviewed by many helpful reviewers. Lead reviewer for this tutorial was Randy Schmidt. Interested in reviewing my upcoming MSDN articles? If so, drop me a line at mitchell@4GuysFromRolla.com.