For various reasons, you might not know until run time what templates you need or what text or controls should be in them. In that case, you need to be able to create the templates dynamically (in code).
Note You can also create templates as Web Forms user controls and bind them dynamically to controls on your page. For details, see Creating a Templated User Control.
You can create templates in code for all controls that use templates: the DataList, Repeater, and DataGrid controls. For the DataGrid control, you use templates to define columns instead of the row-like templates for the other two controls.
Note There are a few differences when creating template columns for the DataGrid control. For details, see Creating Templates Programmatically in the DataGrid Control.
To create dynamic templates, you create a template class that you can then instantiate when needed.
Note For background on creating classes in Visual Basic .NET, see Understanding Classes. For similar information for Visual C# .NET, see class.
To create a template class
Tip A type-safe way to pass the template type to the constructor is to add a parameter to the constructor with the type ListItemType. The ListItemType enumeration defines the possible template types for the Repeater, DataList, and DataGrid controls.
Note You cannot directly add static text to the Controls collection, but you can create controls like the Literal control or the LiteralControl control, set their Text properties, and then add those controls to the parent collection.
The following example illustrates a complete template class that displays some static text ("Item number:") and a counter. The counter is maintained as a shared or static value (depending on what language you are using) called itemcount
for the class and incremented each time a new item is created.
The class defines an explicit constructor that accepts a ListItemType enumeration value to indicate what type of template is being created. Depending on what type of template is being created, the code creates different types of controls and adds them to the Controls collection of the parent control. The end result is an HTML table with a different background color for the alternating item template.
‘ Visual Basic Private Class MyTemplate Implements ITemplate Shared itemcount As Integer = 0 Dim TemplateType As ListItemType Sub New(ByVal type As ListItemType) TemplateType = type End Sub Sub InstantiateIn(ByVal container As Control) _ Implements ITemplate.InstantiateIn Dim lc As New Literal() Select Case TemplateType Case ListItemType.Header lc.Text = "<TABLE border=1><TR><TH>Items</TH></TR>" Case ListItemType.Item lc.Text = "<TR><TD>Item number: " & itemcount.ToString _ & "</TD></TR>" Case ListItemType.AlternatingItem lc.Text = "<TR><TD bgcolor=lightblue>Item number: " _ & itemcount.ToString & "</TD></TR>" Case ListItemType.Footer lc.Text = "</TABLE>" End Select container.Controls.Add(lc) itemcount += 1 End Sub End Class // C# public class MyTemplate : ITemplate { static int itemcount = 0; ListItemType templateType; public MyTemplate(ListItemType type) { templateType = type; } public void InstantiateIn(System.Web.UI.Control container) { Literal lc = new Literal(); switch( templateType ) { case ListItemType.Header: lc.Text = "<TABLE border=1><TR><TH>Items</TH></TR>"; break; case ListItemType.Item: lc.Text = "<TR><TD>Item number: " + itemcount.ToString() + "</TD></TR>"; break; case ListItemType.AlternatingItem: lc.Text = "<TR><TD bgcolor=lightblue>Item number: " + itemcount.ToString() + "</TD></TR>"; break; case ListItemType.Footer: lc.Text = "</TABLE>"; break; } container.Controls.Add(lc); itemcount += 1; } }
When you have a dynamic template available, you can instantiate it in code.
Note To work with a dynamic template as a column in a DataGrid control, see Creating Templates Programmatically in the DataGrid Control.
To use a dynamic template
The following example shows how to use the dynamic template with a Repeater control. In this example, the templates are instantiated while the page is being loaded and before the control is bound to its data source.
‘ Visual Basic Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Repeater1.HeaderTemplate = New MyTemplate(ListItemType.Header) Repeater1.ItemTemplate = New MyTemplate(ListItemType.Item) Repeater1.AlternatingItemTemplate = _ New MyTemplate(ListItemType.AlternatingItem) Repeater1.FooterTemplate = New MyTemplate(ListItemType.Footer) SqlDataAdapter1.Fill(DsCategories1) Repeater1.DataBind() End Sub // C# private void Page_Load(object sender, System.EventArgs e) { Repeater1.HeaderTemplate = new MyTemplate(ListItemType.Header); Repeater1.ItemTemplate = new MyTemplate(ListItemType.Item); Repeater1.AlternatingItemTemplate = new MyTemplate(ListItemType.AlternatingItem); Repeater1.FooterTemplate = new MyTemplate(ListItemType.Footer); sqlDataAdapter1.Fill(dsCategories1); Repeater1.DataBind(); }
There are various ways to get access to data from within a template class, depending on how you have created the class. A good way is one in which the page architecture itself implements data binding — when you add controls to the template, you also add a handler for their DataBinding event. This event will be raised after the template item has been created with all its controls, and it provides you with an opportunity to fetch data and use it in a control.
Note You cannot embed a data-binding expression as a string when creating controls in the template, as you do when defining templates at design time, because data-binding expressions are converted into code at a stage of page processing that occurs before your template is created.
In the handler for the DataBinding event, you have an opportunity to manipulate the contents of the control. Typically (but not necessarily), you fetch data from somewhere and assign it to the control‘s Text property.
Note For background on data binding in Web Forms pages, see Web Forms Data Binding.
To add data binding to a dynamic template, you must do the following:
To add the data-binding event handler
Note For details on how to add event handlers dynamically, see AddHandler and RemoveHandler (for Visual Basic) and Events Tutorial (for Visual C#).
The following example shows code from the template class illustrating how you can bind a newly created control to a method called TemplateControl_DataBinding
.
‘ Visual Basic Dim lc As New Literal() Case ListItemType.Item lc.Text = "<TR><TD>" AddHandler lc.DataBinding, AddressOf TemplateControl_DataBinding // C# Literal lc = new Literal(); case ListItemType.Item: lc.Text = "<TR><TD>"; lc.DataBinding += new EventHandler(TemplateControl_DataBinding); break;
Note that in this example, the text you add to the literal control‘s Text property is different than in the previous example. It contains only the beginning of the table row and cell for the item template. You will complete the cell and row in the data-binding event handler.
The next step is to create the event handler that will be called when the control is data bound.
To create the handler for the DataBinding event
‘ Visual Basic Private Sub TemplateControl_DataBinding(ByVal sender As Object, _ ByVal e As System.EventArgs) // C# private void TemplateControl_DataBinding(object sender, System.EventArgs e)
The following code illustrates one way to perform data binding within a dynamic template. It shows a complete data-binding event handler for Literal controls being created in a template for a Repeater control.
‘ Visual Basic Private Sub TemplateControl_DataBinding(ByVal sender As Object, _ ByVal e As System.EventArgs) Dim lc As Literal lc = CType(sender, Literal) Dim container As RepeaterItem container = CType(lc.NamingContainer, RepeaterItem) lc.Text &= DataBinder.Eval(container.DataItem, "CategoryName") lc.Text &= "</TD></TR>" End Sub // C# private void TemplateControl_DataBinding(object sender, System.EventArgs e) { Literal lc; lc = (Literal) sender; RepeaterItem container = (RepeaterItem) lc.NamingContainer; lc.Text += DataBinder.Eval(container.DataItem, "CategoryName"); lc.Text += "</TD></TR>"; }
Note If you have multiple types of controls in your templates, you would need to create a different data-binding event handler for each of the control types.
聯(lián)系客服