Dynamically created DropDownList loses ListItems on Postback

I have a page that contains some dynamically created controls (TextBox and DropDownList). When a postback occurs, the TextBoxes keep their values, but the DropDownLists lose their ListItems.
This is quite confusing, since the page level DropDownList also keeps its ListItems. Can anyone see what’s wrong with the code below?

Any help in solving this issue would be greatly appreciated.

<%@ Page Language="VB"%>

<script runat="server">
  Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
    If Not Page.IsPostBack Then
      ddlFixed.Items.Add(New ListItem("12", "13"))
      ddlFixed.Items.Add(New ListItem("14", "15"))
    End If
    Dim i As Integer
    For i = 0 To 3
      Dim ddl As New DropDownList
      ddl.ID = "ddlPage" & i
      ddl.EnableViewState = True
      If Not Page.IsPostBack Then
        ddl.Items.Add(New ListItem("12", "13"))
        ddl.Items.Add(New ListItem("14", "15"))
      End If
      pnlDynamic.Controls.Add(ddl)
      Dim txtBx As New TextBox
      txtBx.ID = "txtPage" & i
      If Not Page.IsPostBack Then
        txtBx.Text = "Preset"
      End If
      pnlDynamic.Controls.Add(txtBx)
    Next
  End Sub
</script>


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
</head>
<body>
  <form id="form1" runat="server" enableviewstate="true">
  <div>
    <br />
    <br />
    <a href="Default.aspx" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">Get-Request</a>
    <br />
    <br />
    <asp:Panel runat="server" ID="pnlDynamic" EnableViewState="true" />    
    <br />
    <br />
    <asp:DropDownList runat="server" ID="ddlFixed" />
    <asp:Button runat="server" ID="btn" Text="Postback"/>
  </div>
  </form>
</body>
</html>

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I have found the solution that will allow me to keep the viewstate across postbacks.
It’s to call TrackViewState of the ItemCollection.

CType(ddl.Items, IStateManager).TrackViewState()

Thanks to all for your help.

This is the working solution:

<%@ Page Language="VB"%>

<script runat="server">
  Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
    If Not Page.IsPostBack Then
      ddlFixed.Items.Add(New ListItem("12", "13"))
      ddlFixed.Items.Add(New ListItem("14", "15"))
    End If
    Dim i As Integer
    For i = 0 To 3
      Dim ddl As New DropDownList
      ddl.ID = "ddlPage" & i
      CType(ddl.Items, IStateManager).TrackViewState()
      If Not Page.IsPostBack Then
        ddl.Items.Add(New ListItem("12", "13"))
        ddl.Items.Add(New ListItem("14", "15"))
      End If
      pnlDynamic.Controls.Add(ddl)
      Dim txtBx As New TextBox
      txtBx.ID = "txtPage" & i
      If Not Page.IsPostBack Then
        txtBx.Text = "Preset"
      End If
      pnlDynamic.Controls.Add(txtBx)
    Next
  End Sub
</script>


<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
  <title></title>
</head>
<body>
  <form id="form1" runat="server" >
  <div>
    <br />
    <br />
    <a href="Default.aspx" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">Get-Request</a>
    <br />
    <br />
    <asp:Panel runat="server" ID="pnlDynamic" />    
    <br />
    <br />
    <asp:DropDownList runat="server" ID="ddlFixed" />
    <asp:Button runat="server" ID="btn" Text="Postback"/>
  </div>
  </form>
</body>
</html>

Method 2

A DDL will maintain its items and selection when viewstate is enabled. A textbox will maintain its contents regardless of viewstate since the resulting html is written back to the server on a postback.

I find it courious that you have all these viewstate statements in your code and markup.

One of several things is happening:

  1. ViewState at the control is disabled
  2. ViewState above the contrl hierachy is disabled (page, form, panel)
  3. You are dynamically adding the control too late in the page cycle for the selection to be loaded from viewstate. Loading in INIT should be fine.

Method 3

May be you need to explicitly activate the ViewState for those DropDownLists…

EDIT: This is what I mean by my last comment…

    <script runat="server">
      Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
        If Not Page.IsPostBack Then
          ddlFixed.Items.Add(New ListItem("12", "13"))
          ddlFixed.Items.Add(New ListItem("14", "15"))

          Dim i As Integer
          For i = 0 To 3
            Dim ddl As New DropDownList
            ddl.ID = "ddlPage" & i
            ddl.EnableViewState = True
            ddl.Items.Add(New ListItem("12", "13"))
            ddl.Items.Add(New ListItem("14", "15"))

            pnlDynamic.Controls.Add(ddl)
            Dim txtBx As New TextBox
            txtBx.ID = "txtPage" & i
            txtBx.Text = "Preset"
            pnlDynamic.Controls.Add(txtBx)
          Next
        End If
      End Sub
   </script>

Method 4

I always use Page_Load and never have trouble like this. Maybe something you could look at.

I generally bind data to controls the first time the page loads, and after that let Viewstate handle postbacks etc. Note that they suggest you bind data during Page_Load

Check out http://support.microsoft.com/kb/305141

Page Events
loadTOCNode(2, ‘moreinformation’);
During the life cycle of an ASP.NET page, a few standard events
that are exposed from the Page object are used frequently. The ASP.NET page framework
automatically connects to (or wires up) appropriate delegate instances at run
time for these methods. This saves you from having to write the necessary “glue
code.” The following list presents the delegate instances that are wired up at
run time in the order in which they are fired:

  • Page_Init: During this event, you can initialize values or connect any
    event handlers that you may have.
  • Page_Load: During this event, you can perform a series of actions to either
    create your ASP.NET page for the first time or respond to client-side events
    that result from a post. The page and control view state have been restored
    prior to this event. Use the IsPostBack page property to check whether this is the first time that the
    page is being processed. If it is the first time, perform data binding. Also,
    read and update control properties.
  • Page_DataBind: The DataBind event is raised when the DataBind method is called at the page level. If you call DataBind on individual controls, it only fires the DataBind event of the controls beneath it.
  • Page_PreRender: The PreRender event is fired just before the view state is saved and the
    controls are rendered. You can use this event to perform any last minute
    operations on your controls.
  • Page_Unload: After a page has finished rendering, the Page_Unload event fires. This event is a good place to perform final cleanup
    work. This includes items such as the cleanup of open database connections,
    discarding objects, or closing those files that are open.

The following list outlines the events that are
non-deterministic:

  • Page_Error: If an unhandled exception occurs during page processing, the Error event fires. The Error event gives you an opportunity to gracefully handle
    errors.
  • Page_AbortTransaction: Transaction events are useful if you want to indicate whether a transaction
    succeeds or fails. This event is commonly used for shopping cart scenarios in
    which this event can indicate the success or failure of an order. This event
    fires when a transaction has been aborted.
  • Page_CommitTransaction: This event fires when a transaction has been committed
    successfully.

Method 5

The list items in a DropDownList are not stored in view state. You’ll have to add them on every postback.

What’s stored in view state is the selected index – ie. the ‘value’ of the control.

Edit: Well, it seems I learned something today. I stand corrected 🙂


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x