views:

4623

answers:

6

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"&gt;
<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>
A: 

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

Tor Haugen
Thanks. Why then are the ddlFixed items recreated although I'm not adding them in the postback cycle?
no correct. ddl items are maintained in viewstate. they only need to be added during the initial load.
Andrew Robinson
A: 

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>
Romias
Thanks. How would I do that?
List View Items do not have a viewstate property. You can only manipulate the viewstate on the DDL.
Andrew Robinson
Thanks Andrew... I was thinking of my current coding and said ListView... not even related :)
Romias
Thanks. But I already explicitly set the EnableViewState on the dynamically created DDLs to True.
@schudel: I always do my Loading logic on OnPageLoad... the first time. May be the Panel is modifying your settings? (I never used a Panel in my ASP.net projects ever... )
Romias
@Romias: I tried to add the controls directly to the form: same result. tried onLoad: same result.
Try doing ALL that logic when IsNotPostBack. You are creating dinamically your controls but JUST adding Items when it is the first time. ddlFixed works because you don't "re-create" it every time.
Romias
@Romias: this is intentional. I do not want to go back to the database on every postback to fill the DropDownLists. Basically I want to have the same behaviour for dynamically created controls as for static controls
A: 

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.
Andrew Robinson
I added the EnableViewState for testing purposes. Since ddlFixed retains its state, so should the Panel and consequently the Ddls. Moving the creation to PreInit or Load didn't help also. I'm baffled...
why all the manipulation of viewstate? try just using all the defaults.
Andrew Robinson
Thanks. The idea was to discurage 'try enabling the viewstate' comments. I started without all the EnableViewStates and it didn't work then either.
why don't u just add your @page directive so that we can see it
DrG
A: 
DrG
Thanks. Unfortunately this doesn't change the behaviour.
+1  A: 

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"&gt;
<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: 

if textbox controls are created on button click then how to save view state of those controls but there can b as many controls as button clicks Plz Help me in this regard

asmasm