FAQ: Why do dynamic controls disappear on postback and not raise events?

Rate It (5)

Last post 05-09-2008 8:01 PM by paul_mendoza. 16 replies.

Sort Posts:

  • FAQ: Why do dynamic controls disappear on postback and not raise events?

    11-25-2007, 1:50 PM
    • Loading...
    • mbanavige
    • Joined on 11-06-2003, 1:29 PM
    • New England, USA
    • Posts 6,852
    • Moderator
      TrustedFriends-MVPs

    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:

    1. Declare a button (Button1) in your page markup
    2. Add an event handler for Button1 and in that handler, create a new dynamic button (Button2)
    3. Wire up and event handler for Button2
    4. Page loads an you see Button1
    5. Click on Button1 and the page posts-back Button1's Click event fires and you now see Button1 and Button2
    6. Click on Button2 and...the page posts-back, Button2 disappears and no event for Button2 is raised.

    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:

    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
    
     

     

    Mike Banavige
    ~~~~~~~~~~~~
    Dont forget to click "Mark as Answer" on the post that helped you.
    This credits that member, earns you a point and marks your thread as Resolved so we will all know you have been helped.
  • Re: FAQ: Why do dynamic controls disappear on postback and not raise events?

    11-25-2007, 2:17 PM

    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

  • Re: FAQ: Why do dynamic controls disappear on postback and not raise events?

    11-26-2007, 1:07 AM

     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. 

    Regards
    Ganesan S
    "Hard Work Never Fails"

    Please "Mark as Answered" if helpful for you.
  • Re: FAQ: Why do dynamic controls disappear on postback and not raise events?

    11-26-2007, 8:24 AM
    • Loading...
    • mbanavige
    • Joined on 11-06-2003, 1:29 PM
    • New England, USA
    • Posts 6,852
    • Moderator
      TrustedFriends-MVPs

    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.

     

    Mike Banavige
    ~~~~~~~~~~~~
    Dont forget to click "Mark as Answer" on the post that helped you.
    This credits that member, earns you a point and marks your thread as Resolved so we will all know you have been helped.
  • Re: FAQ: Why do dynamic controls disappear on postback and not raise events?

    11-28-2007, 4:26 PM
    • Loading...
    • Tengo
    • Joined on 10-28-2007, 11:08 AM
    • Posts 147

    Hi, can you please post it in C#?

    Thanks.

  • Re: FAQ: Why do dynamic controls disappear on postback and not raise events?

    12-03-2007, 4:36 AM
    • Loading...
    • imsaudi1
    • Joined on 12-03-2007, 9:24 AM
    • Posts 1

     

    thanks
  • Re: FAQ: Why do dynamic controls disappear on postback and not raise events?

    12-18-2007, 5:29 PM
    • Loading...
    • fpendino
    • Joined on 12-11-2007, 5:53 PM
    • Posts 24

    When using AddHandler, will this work when the control is created within a seperate class?

  • Re: FAQ: Why do dynamic controls disappear on postback and not raise events?

    12-18-2007, 7:46 PM
    • Loading...
    • mbanavige
    • Joined on 11-06-2003, 1:29 PM
    • New England, USA
    • Posts 6,852
    • Moderator
      TrustedFriends-MVPs

    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 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
     
    Mike Banavige
    ~~~~~~~~~~~~
    Dont forget to click "Mark as Answer" on the post that helped you.
    This credits that member, earns you a point and marks your thread as Resolved so we will all know you have been helped.
  • Re: FAQ: Why do dynamic controls disappear on postback and not raise events?

    01-09-2008, 5:00 PM
    • Loading...
    • pshisbey
    • Joined on 02-15-2006, 3:58 PM
    • Posts 11

    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.

  • dynamic control help plzzzzzzzzzzzzzzz.....

    03-10-2008, 1:32 AM
    • Loading...
    • amitha
    • Joined on 03-07-2008, 6:44 AM
    • Posts 8

    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 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

    End Class

  • Re: FAQ: Why do dynamic controls disappear on postback and not raise events?

    04-04-2008, 11:41 AM
    • Loading...
    • sal zaki
    • Joined on 04-04-2008, 3:36 PM
    • Posts 1

    Nice article

  • Re: FAQ: Why do dynamic controls disappear on postback and not raise events?

    04-08-2008, 4:32 AM