RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Nested DataGrids Simplify Hierarchical Data Display : Page 4

Learn how to use nested DataGrids to display hierarchical data and avoid the maintenance nightmare of dynamically-created HTML tables.

Finding Your Orders
The Orders Advanced Search page allows users to locate customers' previous orders and does double duty as an order history report. The search criteria page takes zero or more customer demographics, an optional customer, and a required date range. More relevant is what the page returns:

Figure 6. Orders Advanced Search Schema: This schema shows the tables and relationships returned by the Orders Advanced Search page.
  • Orders—including order date, customer and shipper.
  • Products related to each Order—including product name and quantity.
  • A count of products ordered for the current customer and current product, for each month in the date range.
The strongly typed dataset that holds the search results is shown in Figure 6. You can find the schema in the download that accompanies this article.

The normalized approach to holding data greatly simplifies displaying it hierarchically in the user interface. Figure 7 shows the loops in the page.

ProductMonthCounts—Where Things Get Interesting
There is a lot going on in the page with five separate multi-record controls nested three levels deep. First, each is bound using a different approach. The outermost loop for products is bound in the code-behind page; the nested loops are bound using data-binding syntax; and the innermost loop, for ProductMonthCounts, is bound in the ItemDataBound event of the nested OrderDetails (products) Repeater.

Figure 7. Loops In Search Results: The arrows show the inner and outer loops required to display the hierarchical data.
The innermost loop is the most complex. You have to bind it in the ItemDataBound event primarily because it requires a custom sort order. The custom sorting is required because the database doesn't return months where no products were sold; the middle tier inserts those records. Consequently, the order of records is incorrect in the dataset. The relevant section of code sorts by the FirstDayInMonth field and binds to records that match the current product and customer:

   string strCriteria = String.Format(
     "ProductId={0} AND CustomerID='{1}'", 
   rptProductCountMonths.DataSource = 
Another interesting aspect of the innermost loop is the code that dynamically sets the background color to a deeper shade depending on the number of orders sold.

   <td style='background-color: <%# GetBgColorFromQuantity(
     false) %>'> … </td>
GetBgColorFromQuanity() takes a quantity of products sold, computes red, green, and blue values and returns an HTML color with a call to:

     System.Drawing.Color.FromArgb(intRed, intGreen, intBlue)
This is yet another application of the data-binding syntax.

Even if you don't need to display hierarchical data frequently, a thorough understanding of control hierarchy, data-binding syntax, and events of multi-record controls will empower your code and help you create more robust and maintainable solutions. At first, using nested controls may seem more complicated than the traditional approach of building HTML tables in code, but when you're asked to change your UI the day the application is due, you'll be glad you did.

Lee Richardson works as a senior software engineer for the Near Infinity consulting company, specializing in ASP.Net, SharePoint, and other rapid application development technologies. Lee has nine years of software development experience, is a Microsoft Certified Solution Developer (MCSD), and a Project Management Professional (PMP). For related topics see Lee's blog.
Email AuthorEmail Author
Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date