Introduction
Many a times we wonder how to add a template column dynamically. This might be the case when the number of columns, column types etc., cannot be decided during design time. For example, if the data source of a GridView
control will be retrieved from a Business Layer, when designing the GridView
user interface, the developer can not determine the number of columns and other things related to column description. In such a case, the GridView
will be configured to generate columns automatically at runtime. Adding template columns at runtime was not possible in earlier versions of .NET, i.e., 1.0. With the new version of .NET 2.0 onwards, there is a facility to add template columns at runtime dynamically.
For the above purpose, I have created a class DynamicTemplate
inheriting the ITemplate
interface.
public class DynamicTemplate : System.Web.UI.ITemplate
Now the very first step is to implement the constructor for the class:
public DynamicTemplate(System.Web.UI.WebControls.ListItemType type)
{
templateType = type;
}
Here I have passed ListItemType
as a parameter to the constructor, which will define the type of the current template. I.e., the template can be a Header
, Item
, AlternatingItem
, or Footer
.
Next, for defining the type of the control template column will be displaying, I have added the following method:
public void AddControl(WebControl wbControl,
String BindPropertyName, String BindExpression)
{
htControls.Add(htControls.Count, wbControl);
htBindPropertiesNames.Add(htBindPropertiesNames.Count, BindPropertyName);
htBindExpression.Add(htBindExpression.Count, BindExpression);
}
Here we need to pass three parameters: wbcontrol
is the reference to any web control which we want our template column to display, BindPropertyName
is the property name of the control to be bound, e.g., the Text
property for a TextBox
or Label
control, and BindExpression
is the field name or any valid Bind expression to be evaluated and assigned to the BindProperty
.
Now for providing template column functionality, we need to implement the 'InstantiateIn
' method. This method will be called for every row of the GridView
before binding occurs.
public void InstantiateIn(System.Web.UI.Control container)
{
PlaceHolder ph = new PlaceHolder();
for (int i = 0; i < htControls.Count; i++)
{
Control cntrl = CloneControl((Control)htControls[i]);
switch (templateType)
{
case ListItemType.Header:
break;
case ListItemType.Item:
ph.Controls.Add(cntrl);
break;
case ListItemType.AlternatingItem:
ph.Controls.Add(cntrl);
ph.DataBinding += new EventHandler(Item_DataBinding);
break;
case ListItemType.Footer:
break;
}
}
ph.DataBinding += new EventHandler(Item_DataBinding);
container.Controls.Add(ph);
}
Here, we first clone the web control so that a new copy can be created, and then we add this new copy to the desired placeholder.
Next, we want to implement this class for adding the template column dynamically:
TemplateField t = new TemplateField();
DynamicTemplate mt = new DynamicTemplate(ListItemType.Item);
TextBox t1 = new TextBox();
t1.ID = "txt";
t1.Visible = true;
t1.Text = "1";
mt.AddControl(t1, "Text", "Sno");
Here we are creating a template column which will display a TextBox
. And the Text
property of this TextBox
will be bound with the Sno
data field of the configured data source.
A complete implementation of the above class is attached with this article, which is quite self-explanatory and simple.