Oct
06
2006
Coding the grouping repeater
Posted by admin under
Controls
This is part 5 of this tutorial on how to create a expandable/collapsible grouping repeater control with ASP.NET. So, please start by reading part 1.
Now lets move on to the ASP.NET code. The repeater control ASPX tags looks like this:
<asp:Repeater ID="rptOrder" runat="server" OnItemDataBound="rptOrder_ItemDataBound" EnableViewState="false">
<HeaderTemplate>
<table id="table2" class="treetable">
<tr>
<th>Group</th>
<th>Orderid</th>
<th>Orderdate</th>
<th>RequiredDate</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr runat="server" id="rowGroupHeader">
<td colspan="4"><span runat="server" id="idClickable"><asp:Image ID="idImage" runat="server" ImageUrl="images/minus.gif" CssClass="button" Width="16" Height="16" /><asp:Label ID="lblGroupName" runat="server" Font-Bold="true"></asp:Label></span></td>
</tr>
<tr runat="server" id="rowItem">
<td> <%# DataBinder.Eval(Container.DataItem, "CustomerId") %></td>
<td class="number"><%# DataBinder.Eval(Container.DataItem, "OrderId") %></td>
<td class="number"><%# DataBinder.Eval(Container.DataItem, "OrderDate") %></td>
<td class="number"><%# DataBinder.Eval(Container.DataItem, "RequiredDate") %></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Although we are creating a sort of nested control (grouping can be seen as a kind of nesting ) - I have decided to not use nested repeaters. I believe it will be somewhat faster, not having to do multiple databinds. Just one pass and we are done.
The HeaderTemplate contains the table starting tag and defines the columns - and the footer defines the end tags for the table. However, the whole secret lies within the ItemTemplate:
As you can see we have two tr. One called rowGroupHeader and the other rowItem. I will modify the datasource to include extra (special marked) rows for each group header (same technique as in the article Insert user control every N records in gridview).
In ItemDataBound - if the item is a group header we will show the rowGroupHeader and hide the rowItem - and vice versa.
The code looks like this:
protected void rptOrder_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
HtmlTableRow rowHeader = e.Item.FindControl("rowGroupHeader") as HtmlTableRow;
HtmlTableRow rowItem = e.Item.FindControl("rowItem") as HtmlTableRow;
//Check if it is groupheader
DataRowView oRow = e.Item.DataItem as DataRowView;
if (oRow["poorman_type"].ToString() == "groupheader")
{
Image oImage = e.Item.FindControl("idImage") as Image;
m_oGroupingHelper.AddGroup(rowHeader.ClientID, oImage.ClientID);
HtmlGenericControl oCtrl = e.Item.FindControl("idClickable") as HtmlGenericControl;
oCtrl.Attributes["onclick"] = "javascript:" + m_oGroupingHelper.CurrentGroupItem.FunctionName + "();";
string sThisGroupValue = oRow[DropDownList1.SelectedValue].ToString();
rowHeader.Visible = true;
rowItem.Visible = false;
//Bind group stuff
Label lblGroupname = e.Item.FindControl("lblGroupname") as Label;
lblGroupname.Text = sThisGroupValue;
}
else
{
if (DropDownList1.SelectedValue != "None")
m_oGroupingHelper.CurrentGroupItem.AddClientRow(rowItem.ClientID);
rowHeader.Visible = false;
rowItem.Visible = true;
}
}
}
The secret in how to see if it's a header item lies in
if (oRow["poorman_type"].ToString() == "groupheader")
However, more about that - lets start from the beginning - what happens page is loaded first time or the button Run is clicked.
READ PART 6