I have tweaked this to addi usercontrol dynamically. I was able to add on buton click event 1 time, but I wanted to add usercontrol N number time. N->> number of button hits by the end user.
Now I need to fig out how to retain the value using viewstate in my usercontrol.
If the controls are created in Page_Load() event, it will disappear on postback and will not raise events. this happens because the control could not be initialized in Page_Load() event.
To retain the controls, it can be created within Page_Init() event.
I have tweaked this to addi usercontrol dynamically. I was able to add on buton click event 1 time, but I wanted to add usercontrol N number time. N->> number of button hits by the end user.
Now I need to fig out how to retain the value using viewstate in my usercontrol.
You could add your counter to viewstate and simply keep track of the number of controls you need to dynamically create. Then on each postback during the Page_Load event, you check your counter that was stored in viewstate and recreate the number of dynamic
controls indicated by that counter. In order to insure that the dynamic controls behave properly, you need to also insure that they get consistent ID's. So i would use the counter to help create those controls ids. so your controls would end up getting
ids like; dynamicControl1, dynamicControl2, dynamicControl3 ...
To simplify accessing a counter in viewstate, i like to wrap that up in a page property. Theres an example of that in this wiki article:
http://wiki.asp.net/page.aspx/58/viewstate/
'this property will be used to keep track of
'how many dynamic controls were created.
Private Property TextboxCounter() As Integer
Get
Dim o As Object = ViewState("TextboxCounter")
If o Is Nothing Then Return 0
Return DirectCast(o, Integer)
End Get
Set(ByVal value As Integer)
ViewState("TextboxCounter") = value
End Set
End Property
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'recreate dynamic controls on all postback by page_load at the latest
'we use page_load instead of init so that we can access viewstate.
If Page.IsPostBack Then
For i As Integer = 1 To TextboxCounter
Dim ctrl As New TextBox
'It's very important to specify the controls ID
ctrl.ID = "dynamicTextBox" & i
Me.PlaceHolder1.Controls.Add(ctrl)
Next
End If
End Sub
Protected Sub cmdAddTextbox_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdAddTextbox.Click
'increment counter
TextboxCounter += 1
'add new dynamic control
Dim ctrl As New TextBox
ctrl.ID = "dynamicTextBox" & TextboxCounter
Me.PlaceHolder1.Controls.Add(ctrl)
End Sub
Protected Sub cmdProcessControls_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdProcessControls.Click
'loop through any textbox controls and see what they contain
For Each ctrl As TextBox In Me.PlaceHolder1.Controls
Response.Write(String.Format("Control ID: {0}, Text: {1} <br/>", ctrl.ID, ctrl.Text))
Next
End Sub
this is exactly what I was looking for, I was trying to achieve that via page init event and using __EVENTTARGET, but for some reasons for button __EVENTTARGET was null, than I read somewhere button and image button do not support that. I replaced that
with link button, but FindContorl would't find the link button id, because I was using master page.. your solution worked like butter on hot pan!! thanks
If Viewstate is used to store the value of dynamic contrlols then Page_Load is the event to be used. ViewState values are available in Page_Load - but they are not available during the Page_Init event.
If you look @ the PageLoad life cycle then you will see LoadViewState() executes after the Page_Init() so you can not have ViewState values in Page_Init().
Soumen
Budhi Hin Tanu Janike, Sumirau Pavan Kumar
Bal budhi Vidya dehu mohe,Harahu Kalesa Vikar
[My Site: WCF, My Site and Silverlight site @ Silverlight version].
i use the example to adding N number of dynamic controls to a page . I want to create dropdownlist populate by Dataset and in cmdProcessControls_Click I wanto to show the item choise by user in dropdownlist but I don't get the same behaviour. When Click
in cmdProcessControls button i view dropdownlist without item and label control empty. If I use dropdownlist populate by listitems It works.
private int StepCounter
{
get
{
object o1 = ViewState["StepCounter"];
if (o1 == null) return 0;
return (int)o1;
}
set { ViewState["StepCounter"] = value; }
}
void Page_PreRender()
{
cmdProcessControls.Enabled = StepCounter > 0;
}
protected void Page_Load(object sender, EventArgs e)
{
//recreate dynamic controls on all postback by page_load at the latest
//we use page_load instead of init so that we can access viewstate.
if (Page.IsPostBack)
{
for (int j = 1; j <= StepCounter; j++)
{
DropDownList ddltest = new DropDownList();
ddltest.ID = "ddltest" + j;
//ddltest.AutoPostBack = false;
Label lblDomanda = new Label();
lblDomanda.ID = "lblD" + j;
Label lblTest = new Label();
lblTest.ID = "lbl" + j;
this.PlaceHolder1.Controls.Add(lblDomanda);
this.PlaceHolder1.Controls.Add(lblTest);
this.PlaceHolder1.Controls.Add(ddltest);
}
}
else
{
Label lblTest = new Label();
lblTest.Text = "Inizio Procedura Guidata. Clicca su Add Domanda per Proseguire";
this.PlaceHolder1.Controls.Add(lblTest);
}
}
protected void cmdProcessControls_Click(object sender, EventArgs e)
{
string tipoControl = string.Empty;
foreach (Control ddl in this.PlaceHolder1.Controls)
{
tipoControl = ddl.GetType().ToString();
if ( tipoControl == "System.Web.UI.WebControls.DropDownList")
Response.Write(string.Format("Control ID: {0}, Text: {1} <br/>", ((DropDownList)ddl).ID, ((DropDownList)ddl).SelectedValue));
else if (tipoControl == "System.Web.UI.WebControls.Label")
Response.Write(string.Format("LABEL ID: {0}, Text: {1} <br/>", ((Label)ddl).ID, ((Label)ddl).Text));
}
}
protected void cmdAddTextbox_Click(object sender, EventArgs e)
{
string prova = string.Empty;
SqlDataAdapter sdaDomande;
SqlDataAdapter sdaRisposte;
string constr = ConfigurationManager.ConnectionStrings["ProteoConnectionString"].ConnectionString;
SqlConnection connection = new SqlConnection(constr);
if (StepCounter == 0)
{
sdaDomande = new SqlDataAdapter("SELECT ID_Domanda, Testo, ID_Domanda_Padre, Valore FROM Domande WHERE ID_Domanda = ID_Domanda_Padre ORDER BY ID_Domanda", connection);
}
else
{
sdaDomande = new SqlDataAdapter("SELECT ID_Domanda, Testo, ID_Domanda_Padre, Valore FROM Domande WHERE ID_Domanda = @ID_Domanda_Padre ORDER BY ID_Domanda", connection);
}
DataSet ds = new DataSet();
sdaDomande.Fill(ds, "Domande");
//prova = "D" + ds.Tables["Domande"].Rows[0]["ID_Domanda"].ToString() + "-" + ds.Tables["Domande"].Rows[0]["Testo"].ToString();
sdaRisposte = new SqlDataAdapter("SELECT * FROM Risposte WHERE ID_Domanda = @ID_Domanda ORDER BY ID_Risposta, ID_Domanda", connection);
DataSet dsRisp = new DataSet();
//increment counter
StepCounter += 1;
for (int i = 0; i <= ds.Tables["Domande"].Rows.Count - 1; i++)
{
prova = ds.Tables["Domande"].Rows[i]["ID_Domanda"].ToString();
sdaRisposte.SelectCommand.Parameters.Add("@ID_Domanda", SqlDbType.Int).Value = prova;
sdaRisposte.Fill(dsRisp, "Risposte");
//add new dynamic control
DropDownList ddltest = new DropDownList();
ddltest.DataSource = dsRisp;
ddltest.ID = "ddltest" + StepCounter;
ddltest.AutoPostBack = false;
ddltest.DataTextField = "Testo";
ddltest.DataValueField = "ID_Risposta";
ddltest.DataBind();
Label lblDomanda = new Label();
lblDomanda.Text = "D" + ds.Tables["Domande"].Rows[i]["ID_Domanda"].ToString() + "-" + ds.Tables["Domande"].Rows[i]["Testo"].ToString();
lblDomanda.ID = "lblD" + StepCounter;
Label lblTest = new Label();
lblTest.Text = "Seleziona Risposta";
lblTest.ID = "lbl" + StepCounter;
this.PlaceHolder1.Controls.Add(lblDomanda);
this.PlaceHolder1.Controls.Add(lblTest);
this.PlaceHolder1.Controls.Add(ddltest);
}
}
mbanavige
All-Star
134980 Points
15429 Posts
ASPInsiders
Moderator
MVP
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Mar 20, 2009 01:15 PM|LINK
You would need to use FindControl to get a reference to the dynamic control. Once you have a reference to it, you can then access its properties.
blbirajdar02
Member
188 Points
78 Posts
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Jun 23, 2009 02:22 PM|LINK
Thanks for the post. I have implemented the AJAX tabs to be added dynamically based on your post.
Pune, India
miteshsura
Member
41 Points
26 Posts
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Jul 07, 2009 01:58 AM|LINK
thanks for posting this.
I have tweaked this to addi usercontrol dynamically. I was able to add on buton click event 1 time, but I wanted to add usercontrol N number time. N->> number of button hits by the end user.
Now I need to fig out how to retain the value using viewstate in my usercontrol.
ranjit.verma
Member
8 Points
5 Posts
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Jul 10, 2009 11:16 AM|LINK
If the controls are created in Page_Load() event, it will disappear on postback and will not raise events. this happens because the control could not be initialized in Page_Load() event.
To retain the controls, it can be created within Page_Init() event.
mbanavige
All-Star
134980 Points
15429 Posts
ASPInsiders
Moderator
MVP
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Jul 10, 2009 02:22 PM|LINK
You could add your counter to viewstate and simply keep track of the number of controls you need to dynamically create. Then on each postback during the Page_Load event, you check your counter that was stored in viewstate and recreate the number of dynamic controls indicated by that counter. In order to insure that the dynamic controls behave properly, you need to also insure that they get consistent ID's. So i would use the counter to help create those controls ids. so your controls would end up getting ids like; dynamicControl1, dynamicControl2, dynamicControl3 ...
To simplify accessing a counter in viewstate, i like to wrap that up in a page property. Theres an example of that in this wiki article: http://wiki.asp.net/page.aspx/58/viewstate/
mbanavige
All-Star
134980 Points
15429 Posts
ASPInsiders
Moderator
MVP
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Jul 10, 2009 02:47 PM|LINK
Here's a quick example of adding N number of dynamic controls to a page.
First the markup:
<form id="form1" runat="server"> <div> <asp:Button ID="cmdProcessControls" runat="server" Text="Process" /> <asp:Button ID="cmdAddTextbox" runat="server" Text="Add Textbox" /> <asp:PlaceHolder ID="PlaceHolder1" runat="server" /> </div> </form>Now the code-behind:
'this property will be used to keep track of 'how many dynamic controls were created. Private Property TextboxCounter() As Integer Get Dim o As Object = ViewState("TextboxCounter") If o Is Nothing Then Return 0 Return DirectCast(o, Integer) End Get Set(ByVal value As Integer) ViewState("TextboxCounter") = value End Set End Property Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 'recreate dynamic controls on all postback by page_load at the latest 'we use page_load instead of init so that we can access viewstate. If Page.IsPostBack Then For i As Integer = 1 To TextboxCounter Dim ctrl As New TextBox 'It's very important to specify the controls ID ctrl.ID = "dynamicTextBox" & i Me.PlaceHolder1.Controls.Add(ctrl) Next End If End Sub Protected Sub cmdAddTextbox_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdAddTextbox.Click 'increment counter TextboxCounter += 1 'add new dynamic control Dim ctrl As New TextBox ctrl.ID = "dynamicTextBox" & TextboxCounter Me.PlaceHolder1.Controls.Add(ctrl) End Sub Protected Sub cmdProcessControls_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdProcessControls.Click 'loop through any textbox controls and see what they contain For Each ctrl As TextBox In Me.PlaceHolder1.Controls Response.Write(String.Format("Control ID: {0}, Text: {1} <br/>", ctrl.ID, ctrl.Text)) Next End Submiteshsura
Member
41 Points
26 Posts
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Jul 10, 2009 08:03 PM|LINK
this is exactly what I was looking for, I was trying to achieve that via page init event and using __EVENTTARGET, but for some reasons for button __EVENTTARGET was null, than I read somewhere button and image button do not support that. I replaced that with link button, but FindContorl would't find the link button id, because I was using master page.. your solution worked like butter on hot pan!! thanks
NisGau
Member
4 Points
2 Posts
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Jul 16, 2009 04:01 PM|LINK
If Viewstate is used to store the value of dynamic contrlols then Page_Load is the event to be used. ViewState values are available in Page_Load - but they are not available during the Page_Init event.
Rimbik
Participant
1359 Points
382 Posts
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Jul 17, 2009 04:59 AM|LINK
Bal budhi Vidya dehu mohe,Harahu Kalesa Vikar
[My Site: WCF, My Site
and Silverlight site @ Silverlight version].
rgenco1
Member
2 Points
4 Posts
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Sep 17, 2009 04:05 PM|LINK
Hi all,
i use the example to adding N number of dynamic controls to a page . I want to create dropdownlist populate by Dataset and in cmdProcessControls_Click I wanto to show the item choise by user in dropdownlist but I don't get the same behaviour. When Click in cmdProcessControls button i view dropdownlist without item and label control empty. If I use dropdownlist populate by listitems It works.
private int StepCounter { get { object o1 = ViewState["StepCounter"]; if (o1 == null) return 0; return (int)o1; } set { ViewState["StepCounter"] = value; } } void Page_PreRender() { cmdProcessControls.Enabled = StepCounter > 0; } protected void Page_Load(object sender, EventArgs e) { //recreate dynamic controls on all postback by page_load at the latest //we use page_load instead of init so that we can access viewstate. if (Page.IsPostBack) { for (int j = 1; j <= StepCounter; j++) { DropDownList ddltest = new DropDownList(); ddltest.ID = "ddltest" + j; //ddltest.AutoPostBack = false; Label lblDomanda = new Label(); lblDomanda.ID = "lblD" + j; Label lblTest = new Label(); lblTest.ID = "lbl" + j; this.PlaceHolder1.Controls.Add(lblDomanda); this.PlaceHolder1.Controls.Add(lblTest); this.PlaceHolder1.Controls.Add(ddltest); } } else { Label lblTest = new Label(); lblTest.Text = "Inizio Procedura Guidata. Clicca su Add Domanda per Proseguire"; this.PlaceHolder1.Controls.Add(lblTest); } } protected void cmdProcessControls_Click(object sender, EventArgs e) { string tipoControl = string.Empty; foreach (Control ddl in this.PlaceHolder1.Controls) { tipoControl = ddl.GetType().ToString(); if ( tipoControl == "System.Web.UI.WebControls.DropDownList") Response.Write(string.Format("Control ID: {0}, Text: {1} <br/>", ((DropDownList)ddl).ID, ((DropDownList)ddl).SelectedValue)); else if (tipoControl == "System.Web.UI.WebControls.Label") Response.Write(string.Format("LABEL ID: {0}, Text: {1} <br/>", ((Label)ddl).ID, ((Label)ddl).Text)); } } protected void cmdAddTextbox_Click(object sender, EventArgs e) { string prova = string.Empty; SqlDataAdapter sdaDomande; SqlDataAdapter sdaRisposte; string constr = ConfigurationManager.ConnectionStrings["ProteoConnectionString"].ConnectionString; SqlConnection connection = new SqlConnection(constr); if (StepCounter == 0) { sdaDomande = new SqlDataAdapter("SELECT ID_Domanda, Testo, ID_Domanda_Padre, Valore FROM Domande WHERE ID_Domanda = ID_Domanda_Padre ORDER BY ID_Domanda", connection); } else { sdaDomande = new SqlDataAdapter("SELECT ID_Domanda, Testo, ID_Domanda_Padre, Valore FROM Domande WHERE ID_Domanda = @ID_Domanda_Padre ORDER BY ID_Domanda", connection); } DataSet ds = new DataSet(); sdaDomande.Fill(ds, "Domande"); //prova = "D" + ds.Tables["Domande"].Rows[0]["ID_Domanda"].ToString() + "-" + ds.Tables["Domande"].Rows[0]["Testo"].ToString(); sdaRisposte = new SqlDataAdapter("SELECT * FROM Risposte WHERE ID_Domanda = @ID_Domanda ORDER BY ID_Risposta, ID_Domanda", connection); DataSet dsRisp = new DataSet(); //increment counter StepCounter += 1; for (int i = 0; i <= ds.Tables["Domande"].Rows.Count - 1; i++) { prova = ds.Tables["Domande"].Rows[i]["ID_Domanda"].ToString(); sdaRisposte.SelectCommand.Parameters.Add("@ID_Domanda", SqlDbType.Int).Value = prova; sdaRisposte.Fill(dsRisp, "Risposte"); //add new dynamic control DropDownList ddltest = new DropDownList(); ddltest.DataSource = dsRisp; ddltest.ID = "ddltest" + StepCounter; ddltest.AutoPostBack = false; ddltest.DataTextField = "Testo"; ddltest.DataValueField = "ID_Risposta"; ddltest.DataBind(); Label lblDomanda = new Label(); lblDomanda.Text = "D" + ds.Tables["Domande"].Rows[i]["ID_Domanda"].ToString() + "-" + ds.Tables["Domande"].Rows[i]["Testo"].ToString(); lblDomanda.ID = "lblD" + StepCounter; Label lblTest = new Label(); lblTest.Text = "Seleziona Risposta"; lblTest.ID = "lbl" + StepCounter; this.PlaceHolder1.Controls.Add(lblDomanda); this.PlaceHolder1.Controls.Add(lblTest); this.PlaceHolder1.Controls.Add(ddltest); } }<head id="Head1" runat="server"> <style type="text/css"> html { font:14px Georgia,Serif; } fieldset { display:block; width:600px; padding:20px; margin:10px; } </style> <title>Wizard</title> </head> <body> <form id="form1" runat="server"> <div> <%-- <asp:Button ID="cmdProcessControls" runat="server" Text="Fine" onclick="cmdProcessControls_Click" /> --%> <%--<asp:Button ID="cmdAddTextbox" runat="server" Text="Add domande" onclick="cmdAddTextbox_Click" /> --%> <asp:Label id="lblStepNumber" Runat="server" /> <fieldset> <legend><asp:Literal ID="ltlStep" runat="server" /></legend> <asp:PlaceHolder ID="PlaceHolder1" runat="server" /> </fieldset> <asp:Button ID="cmdProcessControls" runat="server" onclick="cmdProcessControls_Click" Text="< Fine" CausesValidation="false"/> <asp:Button ID="cmdAddTextbox" runat="server" onclick="cmdAddTextbox_Click" Text="Add domande >" /> </div> </form> </body>I try to reply the idcontrols how explain in your post but my code don't work like I want.
Any ideas to help me?
Thanks,
Roberto