Reputation: 103
I have a page where I create a dynamic table, containing dynamic controls which raise events. It works, but I wan't to re-generate that table in some events (so after page_load) to print table modifications.
I understand the problem, its that at this moment, my controls aren't persisted in the viewstate because they are created after page_load, and their events are not raised. But how could I do this ?
Here is my code:
protected void Page_Load(object sender, EventArgs e)
{
generateTable(); // When pass just here, it works well
}
private void generateTable()
{
Table tbl = new Table();
// Here I create my table with controls
tableContainer.Controls.Clear(); // tableContainer is a Panel fixed in aspx page
tableContainer.Controls.Add(tbl);
}
protected void txt_TextChanged(object sender, EventArgs e)
{
// Do some stuff to change values in the table
generateTable(); // Re-generate (but events will not be raised)
}
UPDATE 1:
I thought about something (which complicate my development), but I should do generateTable which creates all my lines and controls and call it on each page_load. And in the other hand create another method which populate controls ? So in events, I call the second one.
But my table is generated dynamically, and controls can also be added after an event (I have a dropdownlist which create a new line and control in the table, so I'm stuck also here cause I won't see the line at the first postback ?)
Upvotes: 1
Views: 3640
Reputation: 1442
Here is a really good link that describes management of dynamically added controls: https://web.archive.org/web/20050321094957/http://devcenter.infragistics.com/Articles/ArticleTemplate.ASPX?ArticleID=2149
Note that once you add the control in your ASP.NET backend anywhere, you have to set property
ViewState["AddedControl"] = "true";
Also, during postback, your page will be regenerated so at that time you will have to re-create the control and set old values backs.
From the same link:
public void Page_Load() {
if (IsPostBack) {
if (ViewState["AddedControl"] != null) {
// Re-create the control but do not
// restore settings configured outside
// the proc (i.e., MaxLength and BackColor)
TextBox t = AddTextBox();
}
}
}
public void OnClick(object sender, EventArgs e) {
TextBox t = AddTextBox();
// Modify properties outside the proc to
// simulate generic changed to the
// control's view state
t.MaxLength = 5;
t.BackColor = Color.Yellow;
}
public TextBox AddTextBox() {
TextBox ctl = new TextBox();
ctl.Text = "Hello";
placeHolder.Controls.Add(ctl);
// Records that a dynamic control has been added
ViewState["AddedControl"] = "true";
return ctl;
}
Upvotes: 1
Reputation: 6764
You should generate your controls on the PageInit event instead. Controls generated on PageInit are automatically managed by the asp.net framework (you'll get viewstate persistance, raised events, etc...)
Just a side note: On your PageInit, you have to always regenerate the dynamic controls or the framework won't be able to manage them.
Try generating your controls on PageInit, and then changing their properties on the postback event like so:
List<LiteralControl> list = new List<LiteralControl>();
protected void Page_Init(object sender, EventArgs e)
{
generateTable(); // When pass just here, it works well
}
private void generateTable()
{
Table tbl = new Table();
// Here I create my table with controls
int rows = 3;
int cols = 2;
for (int j = 0; j < rows; j++)
{
TableRow r = new TableRow();
for (int i = 0; i < cols; i++)
{
TableCell c = new TableCell();
LiteralControl l = new LiteralControl("row " + j.ToString() + ", cell " + i.ToString());
// save a reference to the control for editing
list.Add(l);
c.Controls.Add(l);
r.Cells.Add(c);
}
tbl.Rows.Add(r);
}
tableContainer.Controls.Clear(); // tableContainer is a Panel fixed in aspx page
tableContainer.Controls.Add(tbl);
}
protected void txt_TextChanged(object sender, EventArgs e)
{
// edit controls here
foreach (LiteralControl ctrl in list)
{
ctrl.Text = "TextChanged";
}
}
Upvotes: 0