Rendering n-column tables using the Repeater control
The ASP.NET Repeater control provides a template-based mechanism for rendering data using Data Binding. A basic usage sample can be found here .
The control uses the <ItemTemplate> tag for declaring HTML that should be rendered for each data item and a <SeparatorTemplate> tag to put some HTML between items. It also supports an <AlternatingItemTemplate> that can useful to render a fancy mixed two-color list or, more seriously, a two-column table. An example:
Page1.aspx
<table border="1">
<asp:Repeater id="Repeater1" runat="server">
<ItemTemplate>
<tr>
<td>
<%# DataBinder.Eval(Container.DataItem, "ProductName") %>
</td>
</ItemTemplate>
<AlternatingItemTemplate>
<td>
<%# DataBinder.Eval(Container.DataItem, "ProductName") %>
</td>
</tr>
</AlternatingItemTemplate>
</asp:Repeater>
</table>
Page1.cs
protected System.Web.UI.WebControls.Repeater Repeater1;
private void Page_Load(object sender, System.EventArgs e)
{
SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI;");
SqlCommand command = new SqlCommand("SELECT TOP 15 ProductId, ProductName FROM Products", connection);
connection.Open();
Repeater1.DataSource = command.ExecuteReader(CommandBehavior.CloseConnection);
Repeater1.DataBind();
}
Resulting HTML
Alice Mutton |
Aniseed Syrup |
Boston Crab Meat |
Camembert Pierrot |
Carnarvon Tigers |
Chai |
Chang |
Chartreuse verte |
Chef Anton's Cajun Seasoning |
Chef Anton's Gumbo Mix |
Chocolade |
Côte de Blaye |
Escargots de Bourgogne |
Filo Mix |
Flotemysost |
But what if need to render, lets say, a 3-column table?
Alice Mutton | Aniseed Syrup | Boston Crab Meat |
Camembert Pierrot | Carnarvon Tigers | Chai |
Chang | Chartreuse verte | Chef Anton's Cajun Seasoning |
Chef Anton's Gumbo Mix | Chocolade | Côte de Blaye |
Escargots de Bourgogne | Filo Mix | Flotemysost |
And generically, a n-column table?
There's no <n-AlternatingItemTemplate> tag for this purpose. Yes, you could just programatically render the required HTML, loosing the design-time support. But you can also achieve this using a template-based approach maintaining design time support, using Data Binding events. Here's how.
A 3-column table using a template-based Repeater
To produce a 3-column table, all you need is render a <TD>...</TD> for each data item, and render a </TR><TR> every 3 items. Besides, you should place a <TR> befere the first item and a </TR> after the last item.
The difficult part on this is the "render a </TR><TR> every 3 items" thing. How can this be achieved using Data Binding? The answer is the ItemDataBound event.
When you invoke DataBind() method on a Data Binding enabled control, you can subscribe an event that is fired when each item is rendered. With some coding on this event, you can programmatically change the presentation of a specific data item. With this in mind, you can just count the items being rendered, and show or hide a separator </TR><TR> every three items.
A full example:
Page1.aspx
<table border="1">
<tr>
<asp:Repeater id="Repeater1" runat="server">
<ItemTemplate>
<td><%# DataBinder.Eval(Container.DataItem, "ProductName") %></td>
</ItemTemplate>
<SeparatorTemplate>
</tr>
<tr>
</SeparatorTemplate>
</asp:Repeater>
</tr>
</table>
Page1.cs
protected System.Web.UI.WebControls.Repeater Repeater1;
protected int counter = 0;
protected int columnCount = 3;
private void Page_Load(object sender, System.EventArgs e)
{
SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI;");
SqlCommand command = new SqlCommand("SELECT TOP 15 ProductId, ProductName FROM Products", connection);
connection.Open();
Repeater1.DataSource = command.ExecuteReader(CommandBehavior.CloseConnection);
Repeater1.ItemDataBound +=new RepeaterItemEventHandler(Repeater1_ItemDataBound);
Repeater1.DataBind();
}
private void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Separator)
if((++counter % columnCount) != 0)
e.Item.Visible = false;
}
Cool? To get the full source code for this sample e-mail the author aribeiro@microsoft.com