Click here to Skip to main content
Click here to Skip to main content

Nested and Grouped Repeaters

, 15 Aug 2005
Rate this:
Please Sign up or sign in to vote.
Create a data-driven report web page with nested ASP.NET repeaters.

Introduction

Using nested ASP.NET Repeaters, you can easily create professional report style web pages, that include standard ASP.NET controls. Other articles on CodeProject show how you can do this with a UserControl. This example, just uses the standard Repeater Control, and in particular the ItemDataBound method to create a sophisticated interface.

Background

I needed to create a report, but the users need to be able to update it via the same interface, so SQL Reporting Services, and Crystal Reports were unsuitable. I had to do a fair amount of research to get round some problem; like DataBinding syntax, techniques to locate the nested control, so I decided to share the results. Thanks to people who posted answers to posts in the excellent MSDN Forum.

Setup

If you wish to run the sample, carry out the following steps:

  1. The connection string needs to be modified to connect to your database instance.
  2. I have included an SQL script that creates the report stored procedure. This needs to be run against the Northwind database.

Data

The stored procedure returns two resultsets from the Northwind database.

  1. Product categories
  2. Products and total sales

A DataSet is populated in the standard way.

Code

<asp:Repeater id="rptProducts" runat="server" 
    OnItemDataBound="rptProducts_ItemDataBound">

For the child repeater, you need to specify the OnItemDataBound method to call in the ASPX file. If you just wire the event in the normal way, it does not get called.

1:  protected void rptProducts_ItemDataBound(object sender, 
            System.Web.UI.WebControls.RepeaterItemEventArgs e)
2:  {
3:    if(e.Item.ItemType == ListItemType.Item || 
        e.Item.ItemType == ListItemType.AlternatingItem)
4:    { 
5:      string product =  
          ((DataRowView)e.Item.DataItem).Row.ItemArray[2].ToString(); 
6:      ImageButton i =  
          (ImageButton)e.Item.Controls[0].FindControl("imgDelete"); 
7:      i.CommandName = "Delete"; 
8:      i.CommandArgument = product; 
9:      string script = string.Format(
              "javascript:alert('Delete Product: {0}');", product); 
10:     i.Attributes.Add("onclick", script); 
11:   }
12: }

When rptProducts_ItemDataBound method is called, we can locate product data by casting the RepeaterItem into a DataRowView. [5] Here, we retrieve the product name, which we use to pass into the CommandArgument of the ImageButton[6-8]. This CommandArgument can be pulled out in the ImageButton_Command event, and then used to delete or modify the relevant product in the database. This method [1] must be protected, and not private, otherwise it will be inaccessible.

1:  private void rptCategories_ItemDataBound(object sender, 
            System.Web.UI.WebControls.RepeaterItemEventArgs e)
2:  {
3:    if(e.Item.ItemType == ListItemType.Item || 
            e.Item.ItemType == ListItemType.AlternatingItem)
4:    {
5:       // find category in RepeaterItem
6:       string category = 
           ((DataRowView)e.Item.DataItem).Row.ItemArray[0].ToString();
7:       Repeater rep = (Repeater)e.Item.FindControl("rptProducts") ;
8:       // pass in category to construct "where clause", 
         // then set DataView as DataSource 
9:       DataView dv = getChildRows(category) ; 
10:      rep.DataSource = dv ; 
11:      rep.DataBind() ; 
12:      // calculate total for product category 
13:      SalesTotal = this.calculateSalesTotals(category) ; 
14:      // Find item in group "footer" and populate label with total 
15:      Repeater r = (Repeater)e.Item.Parent ; 
16:      Label lblSalesTotals = 
                 (Label)r.Controls[e.Item.ItemIndex+ 1].FindControl(
                                                     "lblSalesTotals"); 
17:      lblSalesTotals.Text =  SalesTotal.ToString("C") ; 
18:   }
19: }

The parent repeater ItemDataBound method is responsible for filtering the category data. This is the key piece of code on the page, that performs the nesting. FindControl can return a reference to the child Repeater [7]. A DataView control can then be passed to the child Repeater as the DataSource[9-11]. Finally, we calculate the Sales Totals for the category, for the Group Footer [15-17].

1: private DataView getChildRows(string Filter)
2: {
3:   string whereClause = 
         string.Format("CategoryName = '{0}'", Filter) ; 
4:   DataView dv = new DataView(ds.Tables["Products"], 
                           whereClause, "", 
                           DataViewRowState.CurrentRows) ; 
5:   return dv ; 
6: }

A DataView object is returned with the products that belong to a specified category. The DataView constructor used takes the DataTable, an SQL like where clause, a sort expression, and DataViewRowState[4]. No DataRelations are needed.

Debugging

I found it really helpful to set breakpoints on the ItemDataBound methods and take advantage of the Locals, Watch and Command windows in Visual Studio .NET to locate control/objects. This helps you to locate the controls and objects that you want to manipulate.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

smwhit

United Kingdom United Kingdom
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 Pinmembermanoj kumar choubey9-Feb-12 21:10 
QuestionGridview with many datasource PinmemberAbelan26-Aug-08 16:43 
GeneralReduction of code PinsussTom Pester15-Aug-05 10:51 
GeneralRe: Reduction of code Pinmembersmwhit15-Aug-05 23:41 
GeneralRe: Reduction of code PinmemberTom Pester16-Aug-05 0:14 
GeneralRe: Reduction of code Pinsussanony mous30-Aug-05 13:40 
GeneralRe: Reduction of code PinmemberTom Pester31-Aug-05 1:28 
GeneralNice example PinmemberJim Deer15-Aug-05 4:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 15 Aug 2005
Article Copyright 2005 by smwhit
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid