O
Oleg Ogurok
Hi all,
I'm adding several TemplateColumns to my grid programmatically in Page_Load
because I don't know how many I need at compile time. Inside each
TemplateColumn, I set ItemTemplate to a class derived from ITemplate. There,
I add a couple of TextBoxes inside Itemplate.InstantiateIn() method.
It seems InstantiateIn() method executes only if I do .DataSource and
..DataBind() on my DataGrid. However, I don't want to rebind the date on
postbacks because it's not necessary. I understand that as long as I
reconstruct my controls, the ViewState data will be automatically restored.
This works well on the columns I define inside aspx.
Is there a way to make InstantiateIn() execute or should I rebuild my
columns and their controls in some other method?
Here's my code:
private void Page_Load(object sender, System.EventArgs e)
{
DataTable dtPeriods = dsPeriods.Tables["Periods"];
foreach (DataRow row in dtPeriods.Rows)
{
PeriodColumn periodColumn = new
PeriodColumn(Convert.ToInt32(row["Period"]));
dgForecast.Columns.Add(periodColumn);
}
if (!IsPostBack)
{ dgForecast.DataSource = ds;
dgForecast.DataBind();
}
}
class PeriodColumn : TemplateColumn
{
public PeriodColumn(int periodNo)
{
this.periodNo = periodNo;
HeaderText = periodNo.ToString();
this.HeaderStyle.HorizontalAlign = HorizontalAlign.Center;
ItemTemplate = new PeriodItemTemplate(periodNo);
}
private int periodNo;
}
class PeriodItemTemplate : ITemplate
{
public PeriodItemTemplate(int periodNo)
{ this.periodNo = periodNo;
}
#region ITemplate Members
public void InstantiateIn(Control container)
{
tbCost = new TextBox();
tbCost.Columns = 10;
TextBox tbRevenue = new TextBox();
tbRevenue.ID = "tbRevenue_" + periodNo;
tbRevenue.Columns = 10;
LiteralControl lcCost = new LiteralControl("Cost: ");
LiteralControl lcRevenue = new LiteralControl("Rev: ");
LiteralControl lcSeparator = new LiteralControl("<br>");
container.Controls.Add(lcCost);
container.Controls.Add(tbCost);
container.Controls.Add(lcSeparator);
container.Controls.Add(lcRevenue);
container.Controls.Add(tbRevenue);
}
#endregion
I'm adding several TemplateColumns to my grid programmatically in Page_Load
because I don't know how many I need at compile time. Inside each
TemplateColumn, I set ItemTemplate to a class derived from ITemplate. There,
I add a couple of TextBoxes inside Itemplate.InstantiateIn() method.
It seems InstantiateIn() method executes only if I do .DataSource and
..DataBind() on my DataGrid. However, I don't want to rebind the date on
postbacks because it's not necessary. I understand that as long as I
reconstruct my controls, the ViewState data will be automatically restored.
This works well on the columns I define inside aspx.
Is there a way to make InstantiateIn() execute or should I rebuild my
columns and their controls in some other method?
Here's my code:
private void Page_Load(object sender, System.EventArgs e)
{
DataTable dtPeriods = dsPeriods.Tables["Periods"];
foreach (DataRow row in dtPeriods.Rows)
{
PeriodColumn periodColumn = new
PeriodColumn(Convert.ToInt32(row["Period"]));
dgForecast.Columns.Add(periodColumn);
}
if (!IsPostBack)
{ dgForecast.DataSource = ds;
dgForecast.DataBind();
}
}
class PeriodColumn : TemplateColumn
{
public PeriodColumn(int periodNo)
{
this.periodNo = periodNo;
HeaderText = periodNo.ToString();
this.HeaderStyle.HorizontalAlign = HorizontalAlign.Center;
ItemTemplate = new PeriodItemTemplate(periodNo);
}
private int periodNo;
}
class PeriodItemTemplate : ITemplate
{
public PeriodItemTemplate(int periodNo)
{ this.periodNo = periodNo;
}
#region ITemplate Members
public void InstantiateIn(Control container)
{
tbCost = new TextBox();
tbCost.Columns = 10;
TextBox tbRevenue = new TextBox();
tbRevenue.ID = "tbRevenue_" + periodNo;
tbRevenue.Columns = 10;
LiteralControl lcCost = new LiteralControl("Cost: ");
LiteralControl lcRevenue = new LiteralControl("Rev: ");
LiteralControl lcSeparator = new LiteralControl("<br>");
container.Controls.Add(lcCost);
container.Controls.Add(tbCost);
container.Controls.Add(lcSeparator);
container.Controls.Add(lcRevenue);
container.Controls.Add(tbRevenue);
}
#endregion