Existing code is using an asp:repeater
to build an HTML table. (emphasis on the existing design). This is some partial pseudo-code to generate the table:
<asp:repeater OnItemDataBound="ItemDataBound" ... >
<headertemplate>
<table>
<thead>
<tr>
<td>Date</td>
<td>Type</td>
<td>Action</td>
</tr>
</thread>
</headertemplate>
<itemtemplate>
<tr>
<td><%# GetTextForThis((MyItem)Container.DataItem) %></td>
<td><%# GetTextForThat((MyItem)Container.DataItem) %></td>
<td><%# GetTextForTheOther((MyItem)Container.DataItem) %></td>
</tr>
</itemtemplate>
<footertemplate>
</tbody>
</table>
</footertemplate>
</asp:repeater>
But now it is needed that (some) items display differently, and it is needed that it is done using a COLSPAN=3
, and the entire item will be one cell:
<itemtemplate>
<tr>
<td colspan="3">
<img src="<%# GetImageSrcForFoo((MyItem)Container.DataItem) %>
<a href="<%# GetHrefForFoo((MyItem)Container.DataItem) %>
</td>
</tr>
</itemtemplate>
Given:
How can i do this?
i was hoping for something like:
<itemtemplate id="thisThatTheOtherItemTemplate">
<tr>
<td><%# GetTextForThis((MyItem)Container.DataItem) %></td>
<td><%# GetTextForThat((MyItem)Container.DataItem) %></td>
<td><%# GetTextForTheOther((MyItem)Container.DataItem) %></td>
</tr>
</itemtemplate>
<itemtemplate id="fooItemTemplate">
<tr>
<td colspan="3">
<img src="<%# GetImageSrcForFoo((MyItem)Container.DataItem) %>
<a href="<%# GetHrefForFoo((MyItem)Container.DataItem) %>
</td>
</tr>
</itemtemplate>
and somehow magically be able to have the OnDataBind event tell the repeater which template to use. Is this possble?
Although both answers are right and good, i'd rather use the first suggestion; which involves having display code in the aspx file, rather than building HTML manually in a code-behind. (i don't want to ever have to build HTML in code again)
<itemtemplate>
<asp:PlaceHolder ID="thing1" runat="server">
<tr>
<td><%# GetTextForThis((MyItem)Container.DataItem) %></td>
<td><%# GetTextForThat((MyItem)Container.DataItem) %></td>
<td><%# GetTextForTheOther((MyItem)Container.DataItem) %></td>
</tr>
</asp:PlaceHolder>
<asp:PlaceHolder ID="thing2" visible="false" runat="server">
<tr>
<td colspan="3">
<img src="<%# GetImageSrcForFoo((MyItem)Container.DataItem) %>
<a href="<%# GetHrefForFoo((MyItem)Container.DataItem) %>
</td>
</tr>
</itemtemplate>
and in the code-behind:
protected void myRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
// if the data bound item is an item or alternating item (not the header etc)
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
// get the associated object
Object item = .Item.DataItem;
if (item == null)
return;
Control thing1 = e.Item.FindControl("thing1");
Control thing2 = e.Item.FindControl("thing2");
if (item is MyClassThatICreated)
{
thing1.Visible = false;
thing2.Visible = true;
}
else
{
thing1.Visible = true;
thing2.Visible = false;
}
...
}
Place two ASP:Placeholder controls in your item template. In the codebehind, on the ItemDataBound event, determine which style you want to show, and hide one placeholder.
An alternative to Jonathan's suggestion is to just dynamically build the item on the backend in the ItemDataBound event, some people find that easier to work with, rather than toggling visibility.
I personally in this case would just put a literal in, with mode="Passthrough" and would build it on the backend.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With