The ‘normal’ use case for using templated databound controls like the listview control is to specify the control and the templates in declarative markup and bind the control in the code-behind.
<asp:ListView runat="server" ID="listview">
<LayoutTemplate>
<ol><li runat="server" id="itemPlaceholder" />< span>ol>
< span>LayoutTemplate>
<ItemTemplate>
<li><%#Eval("item") %>< span>li>
< span>ItemTemplate>
< span>asp:ListView>
and in the code-behind:
listview.DataSource = ....
listView.DataBind();
But when you’re building a webpart or a composite control, this is generally not really an option. The way to define templates in the code-behind is to define two classes which implement the ITemplate interface and assign an instance of these classes to the LayoutTemplate and the ItemTemplate properties. (There are a lot more templates you can use, but these are used to show how the concept works.)
The Layout template is the simplest to define:
private class LayoutTemplate : ITemplate
{
public void InstantiateIn(Control container)
{
var ol = new HtmlGenericControl("ol");
var li = new HtmlGenericControl("li") { ID = "itemPlaceholder" };
ol.Controls.Add(li);
container.Controls.Add(ol);
}
}
The only requirement is that it control with the ID itemPlaceHolder, the listview uses this ID to find the control to replace with the item template when databinding.
The InstantiateIn method in the item template is similar to that method in the layout template: a control is created (the same type as previously) and this is added to the container control, effectively replacing the child-control (with the itemPlaceHolder ID) from the layout template. The only difference is that we register for the databinding event of the childcontrol. In the databinding method a reference to the childcontrol is obtained (the sender parameter) and a reference to the current item from the bound collection.
private class ItemTemplate : ITemplate
{
public void InstantiateIn(Control container)
{
var li = new HtmlGenericControl("li");
li.DataBinding += DataBinding;
container.Controls.Add(li);
}
public void DataBinding(object sender, EventArgs e)
{
var container = (HtmlGenericControl)sender;
var dataItem = ((ListViewDataItem)container.NamingContainer).DataItem;
container.Controls.Add( new Literal(){Text = dataItem.ToString() });
}
}
Complete source: FibonacciControl.txt (1.88 KB)