Monday, January 22, 2007

Use different templates in the same DataList

First of all there is no reason not to apply this method to any other templatable control like GridViews or DataGrids. The basic mechanism is the same.

The problem here is how to display different templates for different items (not just for different item types) like when databinding to a general collection of different objects.

Basically all you have to do is use the OnItemCreated event to first load a template (using Page.LoadTemplate) from any user control and then applying it to the DataListItem (using ITemplate.InstantiateIn). But there are a few catches. First of all, the original templates (the ones in the as?x file) are applied before the OnItemCreated event. So if some templates are defined, like ItemTemplate for example, you need to clear the controls in the item before you instantiate your template. Second of all, you cannot declare the OnItemCreated event in the Page_Load method, since it is executed after the OnItemCreated event. But you can declare it in the as?x file.

So let's combine all this into code. First the aspx:
<asp:DataList id="dlMain" runat="server" OnItemCreated="dlMain_ItemCreated" >

nothing fancy. Then the cs code:
protected void dlMain_ItemDataBound(object sender, DataListItemEventArgs e)
ITemplate template1 = e.Item.ItemIndex % 2 == 0
? Page.LoadTemplate("~/ucTest1.ascx")
: Page.LoadTemplate("~/ucTest2.ascx");

That's it! ucTest1 and ucTest2 are two arbitrary user controls I am loading alternatively. For this particular case an AlternatingItemTemplate could have been used, but you get the point.