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

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

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:

  • ViewState at the control is disabled
  • ViewState above the contrl hierachy is disabled (page, form, panel)
  • 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.

  • 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>
    
    链接地址: http://www.djcxy.com/p/42380.html

    上一篇: 我怎样才能让我的简单.NET LRU缓存更快?

    下一篇: 动态创建的DropDownList在Postback上丢失了ListItems