26
2012
Nested Repeaters, do it clean and simple – A Beginner’s Tutorial – Part 2
In my earlier article Nested Repeaters, do it clean and simple – A Beginner’s Tutorial – Part 1 , I showed you how to setup a Repeater to use a database backend to display Categories. In this follow-up Article, we will add a Nested Repeater, allowing you to display a Sub-Category for each Main category.
Some SQL explanation
I’ve seen some pretty nasty database layouts in the past but the Categories table I’ve laid out should be very straightforward. Each Category has a name and a ParentId.
If the ParentId is NULL then it is a Main Category, if the Category is a Sub-Category, then simply set the ParentId to the categoryId of the Main Category. Simple and clean, it also means that you can have subcategories many levels deep.
The Stored Procedure LocadCategories is as straightforward as they come;
ALTER PROCEDURE [dbo].[LoadCategories] AS BEGIN SET NOCOUNT ON; SELECT categoryId, categoryName, parentId FROM categories WHERE (parentId IS NULL) ORDER BY categoryName END
Find all Categories where the ParentId is Null, as stated above, this means that category is a Main Category. Done.
Now, how do we find the SubCategory?
Well, the way this will work is when the Repeater’s row is Databound, the current CategoryId is sent to the DB where we look for any Categories where the ParentId matches the current. This means that any resulting rows are a child (or sub) to this category and will be displayed.
ALTER PROCEDURE [dbo].[LoadSubCategories] ( @parentID int ) AS BEGIN SET NOCOUNT ON; SELECT categoryId, categoryName, parentId FROM categories WHERE (parentId=@parentID) ORDER BY categoryName END
The Code Behind – Nested Repeaters, bringing it all together
In your default.aspx, drag a new repeater to the form, rename and add some
This is a Nested Repeater.
<form id="form1" runat="server">
<div>
<asp:Repeater ID="repCategory" runat="server" >
<ItemTemplate>
<div>
<asp:Label ID="lblCategory" runat="server"></asp:Label>
<div>
<asp:Repeater ID="repSubCategory" runat="server" OnItemDataBound="repSubCategory_ItemDatabound">
<ItemTemplate>
<div style="margin-left:8px;">
<asp:Label ID="lblSubCategory" runat="server"></asp:Label>
</div>
</ItemTemplate>
</asp:Repeater>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
</div>
</form>
If you look at it closely, the second repeater is *almost* an exact copy of the first, placed inside the first repeater’s Item Template (obviously with the Control names changed). I’ll get to the differences shortly.
At this point, there’s no code yet to load the content for the second repeater. Let’s do that now.
In the code behind repCategory_ItemDataBound, we will simply add another call to the Database to databind the Nested Repeater under the lblCategory.text assignment. In your default.vb, at this code so repCategory_ItemDataBound looks like this.
Private Sub repCategory_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles repCategory.ItemDataBound
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
Dim lblCategory As Label = Nothing
lblCategory = CType(e.Item.FindControl("lblCategory"), Label)
lblCategory.Text = e.Item.DataItem("categoryName").ToString
'Time to load the SubCategories
Dim repSubCategory As Repeater = Nothing
repSubCategory = CType(e.Item.FindControl("repSubCategory"), Repeater)
Dim param(1) As SqlParameter
param(1) = New SqlParameter("@parentID", SqlDbType.Int)
'The below is the CategoryId of the current row of the MAIN Categories
param(1).Value = e.Item.DataItem("categoryId").ToString
Using reader As SqlClient.SqlDataReader = data_readers.data.ExecuteDataReader("LoadSubCategories", param(1))
If reader.HasRows Then
repSubCategory.DataSource = reader
repSubCategory.DataBind()
End If
End Using
End If
End Sub
You’ll notice that again, this is almost a replica of the code for the MainCategory, though we are now sending a parameter to the LoadSubCategories stored Procedure with the id of the Current Main Category.
One last step remains and that is the Databound Event for the SubCategory repeater repSubCategory.
Add the below code to your default.vb page
Protected Sub repSubCategory_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs)
Dim lblSubCategory As Label = Nothing
lblSubCategory = CType(e.Item.FindControl("lblSubCategory"), Label)
lblSubCategory.Text = e.Item.DataItem("categoryName").ToString
End Sub
What’s happening here? Ok, so when we added the Repeater as a Nested Repeater, we also added OnItemDataBound=”repSubCategory_ItemDatabound” to the control’s parameters. This is because a nested Control, in this case the Nested Repeater, won’t fire its own events, so we have to manually tell the repSubcategory control to fire the repSubCategory_ItemDatabound procedure when that row is Databound.
We could have named the above procedure LoadMySubCategories and it would have worked fine, so long as it was so named in both the Control and the Code Behind.
See Below:
Protected Sub LoadMySubCategories (ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs)
Dim lblSubCategory As Label = Nothing
lblSubCategory = CType(e.Item.FindControl("lblSubCategory"), Label)
lblSubCategory.Text = e.Item.DataItem("categoryName").ToString
End Sub
Conclusion
At this point, you have a functioning, simple Nested Repeater. In many cases, you would replace the label with a HyperLink control to allow a user to navigate using the Categories list. In that case, you would simply amend the code from
Dim lblCategory As Label = Nothing
lblCategory = CType(e.Item.FindControl("lblCategory"), Label)
lblCategory.Text = e.Item.DataItem("categoryName").ToString
to
Dim lnkCategory As HyperLink = Nothing
lnkCategory = CType(e.Item.FindControl("lnkCategory"), HyperLink)
lnkCategory.Text = e.Item.DataItem("categoryName").ToString
lnkCategory.NavigateUrl = “yourNewURL”
In future articles I will address things such as adding buttons or linkButtons in conjunction with the repCategory_ItemCommand.
I sincerely hope these articles have helped to clear things up for someone, I know when I frist started, this was a complete mystery to me. I’ve attached the SQL script inside the .zip file for convenience. If you have any further questions or comments, please feel free to comment below.
Happy Coding!
Comments
Related Posts
Visit my Sponsors
Recent Comments
- Using the Ajax Modal Popup as a Login Control - A Beginner`s Guide - The Everyman Programmer The Everyman Programmer on Using the Ajax Modal Popup as a Login Control – A Beginner`s Guide – Part 2
- Using the Ajax Modal Popup as a Login Control – A Beginner`s Guide - Part 2 - The Everyman Programmer The Everyman Programmer on Passing Parameters to a QueryString – The right way to do it, Encryption
- Using the Ajax Modal Popup as a Login Control – A Beginner`s Guide - Part 2 - The Everyman Programmer The Everyman Programmer on Re-Usable Database Connection Class – A Beginner’s Tutorial Part 1
- Passing Parameters to a QueryString - The right way to do it, Encryption - The Everyman Programmer The Everyman Programmer on asp.Net 4.0 Routing, a simple Tutorial that works
- Nested Repeaters, do it clean and simple – A Beginner's Tutorial – Part 1 - The Everyman Programmer The Everyman Programmer on Re-Usable Database Connection Class – A Beginner’s Tutorial Part 1






