One common error that many have run into when first starting out with creating dynamic page controls is an incorrect assumption that those dynamic controls will survive page postbacks.
For example - a common scenario is to:
<div mce_keep="true">Declare a button (Button1) in your page markup</div>
<div mce_keep="true">Add an event handler for Button1 and in that handler, create a new dynamic button (Button2) </div>
<div mce_keep="true">Wire up and event handler for Button2</div>
<div mce_keep="true">Page loads an you see Button1</div>
<div mce_keep="true">Click on Button1 and the page posts-back Button1's Click event fires and you now see Button1 and Button2</div>
<div mce_keep="true">Click on Button2 and...the page posts-back, Button2 disappears and no event for Button2 is raised.</div>
What happened to Button2?
Since Button2 is not part of your pages declared markup, the framework has no way to know if it should be recreated or not on a postback. You'll need to keep track of the fact that you have
created dynamic control(s) and you will need to add the necessary code to recreate those dynamic control(s) yourself on all subsequent page postbacks. In order for your dynamic control(s)
to work correctly, you'll need to get them all recreated by the Page_Load event
at the latest.
The following example demonstrates how to toggle between 2 different sets of dynamic controls and how to handle events raised from those controls. In this example, I've chosen ViewState as the place where i will store the information needed to know which
dynamic controls need to be recreated on a postback.
Partial Class DynamicControls
Inherits System.Web.UI.Page
Const ALPHABET_SELECTION As String = "ALPHABET"Const NUMBER_SELECTION As String = "NUMBERS"Const VIEWSTATEKEY_DYNCONTROL As String = "DynamicControlSelection"'store property value in viewstate so that it will survive postbacks
Private Property DynamicControlSelection() As String
Get
Dim result As String = ViewState.Item(VIEWSTATEKEY_DYNCONTROL)
If result Is Nothing Then'doing things like this lets us access this property without
'worrying about this property returning null/Nothing
Return String.Empty
Else
Return result
End If
End Get
Set(ByVal value As String)
ViewState.Item(VIEWSTATEKEY_DYNCONTROL) = value
End Set
End Property
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
'running this code on every page_load - even when it's a postback
'check our page property (that we stored in viewstate) to see
'if we need to load a specific set of dynamic controls
Select Case Me.DynamicControlSelection
Case ALPHABET_SELECTION
CreateDynamicAlphabetLinks()
Case NUMBER_SELECTION
CreateDynamicNumberButtons()
Case Else'no dynamic controls need to be loaded...yet
End Select
End Sub
Private Sub onClick(ByVal sender As Object, ByVal e As EventArgs)
'all of the dynamic linkbuttons/buttons will trigger this event handler
'since we used both linkbuttons and regular buttons for our dynamic controls,
'we will cast the sender control to an interface that is common to both
'of those button controls - the IButtonControl interface
Dim btn As IButtonControl = DirectCast(sender, IButtonControl)
Me.lblClickResult.Text = _
String.Format("You clicked - CommandName: {0} CommandArgument: {1}", _
btn.CommandName, btn.CommandArgument)
End Sub
Protected Sub cmdAlphabet_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles cmdAlphabet.Click
'user is selecting to show the dynamic Alphabet buttons
Me.CreateDynamicAlphabetLinks()
End Sub
Protected Sub cmdNumbers_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles cmdNumbers.Click
'user is selecting to show the dynamic Number buttons
Me.CreateDynamicNumberButtons()
End Sub
Private Sub CreateDynamicAlphabetLinks()
'clear the placeholder first - in case something else was dynamically loaded
Me.PlaceHolder1.Controls.Clear()
'dynamically create a series of linkbuttons
For keycode As Integer = 65 To 90 'one for each letter in the alphabet
Dim lnk As New LinkButton
'assign the ID ourself to make sure it is consistent
'if you let the framework assign it, the dynamic control may
'not behave correctly
lnk.ID = "alpha_" & keycode.ToString
lnk.Text = Chr(keycode)
'we'll add a CommandName and a CommandArgument
'so we can determine what was clicked when the event is raised
lnk.CommandName = "ALPHABET"
lnk.CommandArgument = Chr(keycode)
'have them all use the same event handler
AddHandler lnk.Click, AddressOf onClick
'add these dynamic controls to our strategically place placeholder control
'the position of the placeholder determines
'where on the page the dynamic controls will appear
Me.PlaceHolder1.Controls.Add(lnk)
Me.PlaceHolder1.Controls.Add(New LiteralControl(" ")) 'space them out
Next'VERY IMPORTANT -> remember that we created these controls for the next postback
Me.DynamicControlSelection = ALPHABET_SELECTION
End Sub
Private Sub CreateDynamicNumberButtons()
'clear the placeholder first - in case something else was dynamically loaded
Me.PlaceHolder1.Controls.Clear()
'dynamically create a series of button controls
For number As Integer = 0 To 25
Dim btn As New Button
'assign the ID ourself to make sure it is consistent
'if you let the framework assign it, the dynamic control may
'not behave correctly
btn.ID = "number_" & number.ToString
btn.Text = number.ToString
'we'll add a CommandName and a CommandArgument
'so we can determine what was clicked when the event is raised
btn.CommandName = "NUMBER"
btn.CommandArgument = number.ToString
'have them all use the same event handler
AddHandler btn.Click, AddressOf onClick
'add these dynamic controls to our strategically place placeholder control
'the position of the placeholder determines
'where on the page the dynamic controls will appear
Me.PlaceHolder1.Controls.Add(btn)
Me.PlaceHolder1.Controls.Add(New LiteralControl(" ")) 'space them out
Next'VERY IMPORTANT -> remember that we created these controls for the next postback
Me.DynamicControlSelection = NUMBER_SELECTION
End Sub
Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.PreRender
Me.lblViewStateValue.Text = Me.DynamicControlSelection
End Sub
End Class
It is important to note that it is not sufficient to re-create the dynamic controls on all subsequent page postbacks.
You need to re-create them with the same ID's (as shown in the code above). The ID's are important for the event mechanism.
If you don't assign ID's, the ASP.NET engine will assign ID's automatically (something like ctl_01, ctl_02, etc.), and sometimes these ID's may be different before and after the postback (for instance if the number of controls has changed in the mean time).
This remark is already stated in the code above, but I think it is important to keep it in mind as a general rule before you start coding dynamic controls.
The dynamically created control will disappear on postback why because controls are created but initialized on the page load.
That is why whenever the page postback happens the controls will disappear. So if you don't to disappear you control on the post back you should create it in the Page_Init()
Here once created the control won't disappear not only on the page post back but also in the control events.
Regards
Ganesan S
"Hard Work Never Fails"
Please "Mark as Answered" if it is helpful for you.
While you can create dynamic controls in either Page_Init or Page_Load, I chose Page_Load as I was using ViewState to store a value that indicated which set of dynamic controls should be loaded. ViewState values are available in Page_Load - but they are
not available during the Page_Init event. If the control creation logic were to be moved to Page_Init, then the example i posted would not work.
First we need a simple page that contains a PlaceHolder control named PlaceHolder1. In the Page_Init event of our page we can call a separate class to create a dynamic button.
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
'ask a separate class to create a button control in a designated placeholder
'note that it's very important that the dynamic control is created on each and every
'postback and that the dynamic control also has a consistent control ID.
Dim buttonCreator As New DynamicButtonCreator
buttonCreator.CreateButton(Me.PlaceHolder1)
End Sub
So now we need that separate class to both create the dynamic button control and to handle the click event from it.
Public Class DynamicButtonCreator
'this method creates a dynamic button in the designated placeholder
Public Sub CreateButton(ByVal placeHolder As PlaceHolder)
Dim b As New Button
b.ID = "mySpecialButton"
b.Text = "A Dynamic Button"'wire up an event handler
AddHandler b.Click, AddressOf onClick
'add dynamic button to the placeholder
placeHolder.Controls.Add(b)
End Sub
Private Sub onClick(ByVal sender As Object, ByVal e As EventArgs)
'handle the click event from the dynamic button
Dim btn As IButtonControl = DirectCast(sender, IButtonControl)
btn.Text = "You just clicked me..."End Sub
End Class
If you need to access viewstate you can initalize/create dynamic controls in LoadViewState which occurs between Page_Init and Page_Load. In LoadViewstate, access viewstate properties and create the controls , after the base.LoadViewstate call.
Partial
Class testajax
Inherits System.Web.UI.Page
Sub Page_Load(ByVal Sender
As Object,
ByVal E As EventArgs)
If IsPostBack
Then
SubmitBtn_Click(Sender, E)
End If
End Sub
Public
Sub SubmitBtn_Click(ByVal Sender
As Object,
ByVal E As EventArgs)
Dim I As
Integer
For I = 1
To CInt(tbNo.Text.Trim())
Dim tbInhrtrName
As New TextBox
tbInhrtrName.ID = "tbDynamic" & I.ToStringtbInhrtrName.Text =
"Control" & I
Form.Controls.Add(tbInhrtrName)
'Area1.Controls.Add(tbInhrtrName)
Dim MyLiteral =
New LiteralControl
MyLiteral.Text =
"<BR><BR>"
Form.Controls.Add(MyLiteral)
'Area1.Controls.Add(MyLiteral)
Next
submit.Visible =
"true"
tblInheritDetails.Visible =
"true"
End Sub
Protected
Sub calInheritAmnt(ByVal sender
As Object,
ByVal e As System.EventArgs)
Handles submit.Click
Dim id As
String
Dim I As
Integer
'Dim tb As New TextBox
For I = 1
To CInt(tbNo.Text.Trim())
Dim tb As
New TextBox
id = "tbDynamic" & I.ToStringtb =
DirectCast(sender, TextBox)
Response.Write(tb.Text.ToString())
'Response.Write(Session(id) & "<br/>")
Next
End Sub
mbanavige
All-Star
134964 Points
15421 Posts
ASPInsiders
Moderator
MVP
FAQ: Why do dynamic controls disappear on postback and not raise events?
Nov 25, 2007 05:50 PM|LINK
One common error that many have run into when first starting out with creating dynamic page controls is an incorrect assumption that those dynamic controls will survive page postbacks.
For example - a common scenario is to:
What happened to Button2?
Since Button2 is not part of your pages declared markup, the framework has no way to know if it should be recreated or not on a postback. You'll need to keep track of the fact that you have
created dynamic control(s) and you will need to add the necessary code to recreate those dynamic control(s) yourself on all subsequent page postbacks. In order for your dynamic control(s)
to work correctly, you'll need to get them all recreated by the Page_Load event at the latest.
The following example demonstrates how to toggle between 2 different sets of dynamic controls and how to handle events raised from those controls. In this example, I've chosen ViewState as the place where i will store the information needed to know which dynamic controls need to be recreated on a postback.
First - here's the basic page markup:
<form id="form1" runat="server"> <div> <hr /> <asp:Button ID="cmdAlphabet" runat="server" Text="Load Alphabet" /> <asp:Button ID="cmdNumbers" runat="server" Text="Load Numbers" /> <asp:Label ID="lblViewStateValue" runat="server" Text="" EnableViewState="false"></asp:Label> <hr /> <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder> <hr /> <asp:Label ID="lblClickResult" runat="server" Text="" EnableViewState="false"></asp:Label> </div> </form>And here's the associated codebehind:
Jos Branders
Contributor
5210 Points
822 Posts
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Nov 25, 2007 06:17 PM|LINK
It is important to note that it is not sufficient to re-create the dynamic controls on all subsequent page postbacks.
You need to re-create them with the same ID's (as shown in the code above). The ID's are important for the event mechanism.
If you don't assign ID's, the ASP.NET engine will assign ID's automatically (something like ctl_01, ctl_02, etc.), and sometimes these ID's may be different before and after the postback (for instance if the number of controls has changed in the mean time).
This remark is already stated in the code above, but I think it is important to keep it in mind as a general rule before you start coding dynamic controls.
Jos
ganesansanka...
Participant
1187 Points
234 Posts
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Nov 26, 2007 05:07 AM|LINK
Hi,
The dynamically created control will disappear on postback why because controls are created but initialized on the page load.
That is why whenever the page postback happens the controls will disappear. So if you don't to disappear you control on the post back you should create it in the Page_Init()
Here once created the control won't disappear not only on the page post back but also in the control events.
Ganesan S
"Hard Work Never Fails"
Please "Mark as Answered" if it is helpful for you.
mbanavige
All-Star
134964 Points
15421 Posts
ASPInsiders
Moderator
MVP
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Nov 26, 2007 12:24 PM|LINK
While you can create dynamic controls in either Page_Init or Page_Load, I chose Page_Load as I was using ViewState to store a value that indicated which set of dynamic controls should be loaded. ViewState values are available in Page_Load - but they are not available during the Page_Init event. If the control creation logic were to be moved to Page_Init, then the example i posted would not work.
Tengo
Member
435 Points
216 Posts
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Nov 28, 2007 08:26 PM|LINK
Hi, can you please post it in C#?
Thanks.
fpendino
Member
30 Points
27 Posts
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Dec 18, 2007 09:29 PM|LINK
When using AddHandler, will this work when the control is created within a seperate class?
mbanavige
All-Star
134964 Points
15421 Posts
ASPInsiders
Moderator
MVP
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Dec 18, 2007 11:46 PM|LINK
Yes - it will. Consider the following example:
First we need a simple page that contains a PlaceHolder control named PlaceHolder1. In the Page_Init event of our page we can call a separate class to create a dynamic button.
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init 'ask a separate class to create a button control in a designated placeholder 'note that it's very important that the dynamic control is created on each and every 'postback and that the dynamic control also has a consistent control ID. Dim buttonCreator As New DynamicButtonCreator buttonCreator.CreateButton(Me.PlaceHolder1) End SubSo now we need that separate class to both create the dynamic button control and to handle the click event from it.
pshisbey
Member
35 Points
13 Posts
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Jan 09, 2008 09:00 PM|LINK
If you need to access viewstate you can initalize/create dynamic controls in LoadViewState which occurs between Page_Init and Page_Load. In LoadViewstate, access viewstate properties and create the controls , after the base.LoadViewstate call.
amitha
Member
3 Points
8 Posts
dynamic control help plzzzzzzzzzzzzzzz.....
Mar 10, 2008 05:32 AM|LINK
this is my program logic
i am new to this web developement so looking forward for your help
plzzzzzzzzzz go thru
reply asap
having error with find control part
do suggest all changes nedeed
or else
if possible can u modify my code n send rest of my project is going good i am really stuck with this plzz
i hav to take values frm text box n calculate base on it
<form id="frmPension" runat="server"> <asp:Panel id="pnlone" runat="server" Height="74px" Width="384px"> <asp:Label ID="lblAmnt" Text=" Enter the pension amount:" runat="server" Width="180px"></asp:Label> <asp:TextBox id="tbAmnt" runat="server"/><br /> <asp:Label ID="lblNo" Text=" Enter the number of persons:" runat="server" Width="180px"></asp:Label> <asp:TextBox id="tbNo" runat="server"/><br /> <center> <asp:button id="Enter" text="Enter" OnClick="SubmitBtn_Click" runat="server"/></center><br /> <p><asp:PlaceHolder id="Area1" runat="server"></asp:PlaceHolder></p> <table id="tblReslt" runat="server"> <tr> <td id="col1" runat="server"></td> <td id="col2" runat="server"></td> </tr> <tr> <td><asp:Button ID="submit" runat="server" visible="false" OnClick="calInheritAmnt" Text="submit" /></td> </tr> </table> </asp:Panel>
<asp:table id="tblInheritDetails" runat="server" width="100%"/> </form>
Partial Class testajax Inherits System.Web.UI.Page Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs) If IsPostBack ThenSubmitBtn_Click(Sender, E)
End If End Sub Public Sub SubmitBtn_Click(ByVal Sender As Object, ByVal E As EventArgs) Dim I As Integer For I = 1 To CInt(tbNo.Text.Trim()) Dim tbInhrtrName As New TextBox tbInhrtrName.ID = "tbDynamic" & I.ToStringtbInhrtrName.Text = "Control" & IForm.Controls.Add(tbInhrtrName)
'Area1.Controls.Add(tbInhrtrName) Dim MyLiteral = New LiteralControlMyLiteral.Text =
"<BR><BR>"Form.Controls.Add(MyLiteral)
'Area1.Controls.Add(MyLiteral) Nextsubmit.Visible =
"true"tblInheritDetails.Visible =
"true" End Sub Protected Sub calInheritAmnt(ByVal sender As Object, ByVal e As System.EventArgs) Handles submit.Click Dim id As String Dim I As Integer 'Dim tb As New TextBox For I = 1 To CInt(tbNo.Text.Trim()) Dim tb As New TextBox id = "tbDynamic" & I.ToStringtb = DirectCast(sender, TextBox)Response.Write(tb.Text.ToString())
'Response.Write(Session(id) & "<br/>") Next End SubEnd
Classting80427
Member
2 Points
1 Post
Re: FAQ: Why do dynamic controls disappear on postback and not raise events?
Apr 08, 2008 08:32 AM|LINK
why don't use "IsPostBack" in server side to check? seems it works in my case