controls disappearing from placeholder on postback

Posted on 2003-10-24
Last Modified: 2007-12-19
I have  a page upon which I have to add controls at runtime. They are rows of textboxes and dropdownlists, which I name ctrl00...ctrl09 and ctrl10...ctrl19 per row where the first digit is the row and the seecond is the column.

I have used a two dimensional array to initailize the controls to textboxes or dropdownlists, but then I add the control to a placeholder, like this:

 plcCodeLines.Controls.Add(CType(codeLine(index2), System.web.ui.Control))

However I need the user to be able to select from a dropdown list and when they do this another dropdown list is repopulated.

for example accounts are linked to departments, so when a user selects a certain department in a row I want the account dropdown list in the same row to populate with the department specific accounts. I have set these controls postback property to true.

However I can't seem to get a hold of the controls to update them after the postback.

The place holder returns false for  Response.Write(plcCodeLines.HasControls) on the postback.

I can get a hold of the selected values by using request.form("ctrl00")

What is going on?? When I use the trace, I can see the controls in the control tree and the in the form collection (after postback)

Anything to do with viewstate?? This is a server-side web app by the way
Question by:Gezna
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 12

Expert Comment

ID: 9613704
I did this a little different:

Instead of adding the controls as you did, I created the control like this:

        Dim bt As New LinkButton
        With bt
            .Text = strName
            .ID = strID
            .CommandName = strName
            .Enabled = blnEnabled
        End With
        AddHandler bt.Click, AddressOf HandleEvent

As you can see I added a handler to catch the linkbutton's event.
The event is handled in 'HandleEvent' :

    Private Sub HandleEvent(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim strCommand As String
            strCommand = sender.CommandName
        Catch ex As Exception

        End Try
        'do some additional coding
    End Sub

Of course you can do the same for other controls.

If you need more information please let me know!

LVL 28

Assisted Solution

iboutchkine earned 100 total points
ID: 9613868
When you create controls dynamically they will disappear on every postback!!!!!!
Dynamically added controls need to be re-added on each Postback.

When you are creating dynamic controls in a container, you have to recreate each control with every
postback. It seems weird, I know, because after you recreate the dynamic control it's propertires and
values will still be restored by viewstate. You just have to alert your page that these controls still exist
since you are not doing it declaratively.


Add this Property:

'This property will keep track of how many control we have on the page
Private Property ControlCount() As Integer
 Set(ByVal Value As Integer)
   ViewState("ControlCount") = Value
 End Set
   If ViewState("ControlCount") Is Nothing Then
     ViewState("ControlCount") = 0
   End If
   Return ViewState("ControlCount")
 End Get
End Property

Add this sub:

'This sub will call laodcontrol and add the control to the page
Private Sub CreateControl(ByVal intIndex As Integer)
 Dim mySecurityControl As SetSecurityForSystem = LoadControl("SetSecurityForSystem.ascx")
 mySecurityControl.ID = "mySecurityControl" & intIndex
End Sub

Change your click event handler to this:

  'Add a new control and increment our counter when the button is clicked
  Private Sub cmdSetSystemSecurity_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSetSystemSecurity.Click
    ControlCount += 1
  End Sub

Change your Page_Load to this:

  'If the page is posted back, check our counter and re add teh appropriate number of controls
  Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
     Dim intIndex As Integer = 0
     If Page.IsPostback()
       For intIndex = 0 To ControlCount - 1
     End If
  End Sub

LVL 12

Expert Comment

ID: 9614447
iboutchkine is correct, all controls will disappear on a postback.

That's why I've build a seperate WebUserControl which builds the controls for me.
In that WCC the controls are created on each page_load.

Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.


Author Comment

ID: 9614657

That is almost exactly what I am looking for, except the control (a dropdownlist) that triggers the handler when it's selected index has changed, has to update a control (also a dropdown list) based on its selected item.

The dropdown list that has to be updated is also a dynamic control that I can't "get a hold of"

Any more ideas?
LVL 23

Expert Comment

ID: 9616406
Did you add the other dropdown list into the page's control tree before the selected dropdown liist's event handler is invoked. If you haven't done that, you are not going to find it in the event handler. Bottom line is that in Page_Load, reconstruct the controls that were there before post back was fired only then the framework will reinstate the control values from view state,
LVL 12

Accepted Solution

roverm earned 400 total points
ID: 9616866
Hi Gezna,

Ok, build you an example.
The problem is that you can't assign to onchange event and capture that serverside.
However, I faked the postback and now it works.

You need to add a dummy linkbutton to the page, called 'bt'. Just don't set the text (even empty it) so that you won't see it.

Then add a normal input, type hidden. Call it 'thevalue'.
We are going to use this a dummy for retrieving the selected value.

So, this will give you this page (I called it test.aspx):

<%@ Page Language="vb" AutoEventWireup="false" Codebehind="test.aspx.vb" Inherits="VIMWebmailing.test"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
            <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
            <meta content="Visual Basic .NET 7.1" name="CODE_LANGUAGE">
            <meta content="JavaScript" name="vs_defaultClientScript">
            <meta content="" name="vs_targetSchema">
      <script language="javascript">
            function fakeit()
            { var x=fakeit.arguments[0];
              return false;
            <form id="Form1" method="post" runat="server">
                  <asp:placeholder id="plh" runat="server"></asp:placeholder><input name="thevalue" type="hidden">
                  <asp:LinkButton id="bt" runat="server"></asp:LinkButton></form>

As you can see, there's also a javascript function which fills the dummy and fakes the postback.

This is the vb page:
Public Class test
    Inherits System.Web.UI.Page

#Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub
    Protected WithEvents plh As System.Web.UI.WebControls.PlaceHolder
    Protected WithEvents bt As System.Web.UI.WebControls.LinkButton

    'NOTE: The following placeholder declaration is required by the Web Form Designer.
    'Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
    End Sub

#End Region

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim cb As New DropDownList
        With cb
            .Items.Add("this is item 1")
            .Items.Add("and this is item 2")
            .Items.Add("and finally item 3")
            .AutoPostBack = True
        End With
        cb.Attributes.Add("onchange", "javascript:return fakeit(this);")
    End Sub

    Private Sub bt_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles bt.Click
    End Sub
End Class

As you can see the bt_Click event will handle the change of the dropdownlist.

Of course you can use this function to handle all dropdownlists on your form. Just add another hidden input and store the senders name in that.

If you need to know more just let me know.

LVL 12

Expert Comment

ID: 9617524
btw: You can leave the 'AutoPostBack = True' out.
There's no need for that.

Author Comment

ID: 9622418
Hi roverm,

I've modified your page_load a bit to see if you can show me how I would do what I need to do cause it's still a bit unclear to me.

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim cb As New DropDownList
        With cb
            .Items.Add("Department 1")
            .Items.Add("Department 2")
            .Items.Add("Department 3")
            .AutoPostBack = True
        End With
        cb.Attributes.Add("onchange", "javascript:return fakeit(this);")

Dim cb2 As New DropDownList
        With cb2
            .Items.Add("Account 1")
            .Items.Add("Account 2")
            .Items.Add("Account 3")
            .AutoPostBack = True
        End With
cb2.Attributes.Add("onchange", "javascript:return fakeit(this);")
    End Sub

    Private Sub bt_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles bt.Click

Dim selDept As String

selDept = Request.form("cb")


plh.controls.findcontrol("cb2").items.add("Account 4")

    End Sub
End Class

Your first code snippet with the handler almost worked for me except I could only manipulate the control which caused the postback (the sender) and not the second control whose list depends on what value was selected for the sender

Perhaps I'm being a bit dense here, but I'm new to ASP.Net and some of the concepts haven't sunk in yet


LVL 12

Expert Comment

ID: 9622455
Hi Gezna,

The problem is that in a postback the dropdownlists are gone.
So instead of adding an item to the collection you need to recreate the controls on every postback.

Since your data seems to come from a database that shouldn't be a problem.

LVL 12

Expert Comment

ID: 9630118
Gezna, any progress?

Author Comment

ID: 9633716
I've just figured out a  way to do it which is best for me to recreate the controls at postback. A collegue has suggested that I try creating a controls collection on the session level and use it to add my controls the first time and then on every postback reload the control from the collection to the placeholder.

'Here is where the controls collection is declared
Public Class Global
    Inherits System.Web.HttpApplication
      Public Shared sessColl As ControlCollection

    Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires when the session is started
        Dim owner As System.Web.UI.Control = New System.Web.UI.Control
        sessColl = New ControlCollection(owner)

    End Sub
End Class

'Here is the page load on the page that has the dynamic controls
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

If IsPostBack Then
            Dim ctrl As System.Web.UI.Control
            For Each ctrl In sessColl
if not ispostback then
Dim combocount, index2 As integer
                    For comboCount = 0 To BSSds.Tables("combobox").Rows.Count - 1
                          For index2 = 0 To 11
                                   Dim ctrl As Object
                                   If index2 = 0 Or index2 > 7 Then
                                    ctrl = New System.Web.UI.WebControls.TextBox
                                    ctrl = New System.Web.UI.WebControls.DropDownList
                                   End If
                    ctrl.ID = "ctrl" & comboCount & index2
                    If index2 = 1 Or index2 = 3 Or index2 = 8 Or index2 = 9 Then                         ctrl.autopostback = True
                    End If

'Adds the line of coding to the place holder and update the debit and credit totals

                                index2 = index2 + 1
                                combocount = combocount + 1
        Catch ex As Exception
        End Try
     End if
    End Sub

It works great, but you guys really helped me figure out what was going on.

Author Comment

ID: 9633742
Hope I didn't step on any toes, I'm new to the Experts-Exchange world
LVL 12

Expert Comment

ID: 9633746
Great, then please close the question so it will go to the PAQ database.

Just remember that Session state 'eats' your server memory!
LVL 12

Expert Comment

ID: 9633777
Ok, that for closing and the points!
Glad we could help you and welcome to EE!!

Featured Post

Tutorials alone can't teach real engineering

So we built better training tools.

-Hands-on Labs
-Instructor Mentoring
-Scenario-Based Tests
-Dedicated Cloud Servers

All at your fingertips. What are you waiting for?

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

IP addresses can be stored in a database in any of several ways.  These ways may vary based on the volume of the data.  I was dealing with quite a large amount of data for user authentication purpose, and needed a way to minimize the storage.   …
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Monitoring a network: why having a policy is the best policy? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the enormous benefits of having a policy-based approach when monitoring medium and large networks. Software utilized in this v…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …

623 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question