动态创建的DropDownList在Postback上丢失ListItems

时间:2009-03-08 13:56:30

标签: asp.net vb.net drop-down-menu viewstate

我有一个页面,其中包含一些动态创建的控件(TextBox和DropDownList)。发生回发时,TextBox会保留其值,但DropDownLists会丢失其ListItem。 这非常令人困惑,因为页面级DropDownList也保留了ListItems。任何人都可以看到下面的代码有什么问题吗?

非常感谢您解决此问题的任何帮助。

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

5 个答案:

答案 0 :(得分:6)

我找到了一个解决方案,可以让我在回发中保持视图状态。 它是调用ItemCollection的TrackViewState。

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

感谢大家的帮助。

这是可行的解决方案:

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

答案 1 :(得分:0)

可能需要为那些DropDownLists明确激活ViewState ......

编辑:这就是我上次评论的意思......

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

答案 2 :(得分:0)

启用viewstate时,DDL将保留其项目和选择。无论viewstate如何,文本框都将保持其内容,因为生成的html会在回发时写回服务器。

我觉得你在代码和标记中包含所有这些viewstate语句是很有道理的。

其中一件事正在发生:

  1. 控件上的ViewState已禁用
  2. 控制层面上方的ViewState被禁用(页面,表格,面板)
  3. 您正在页面周期中动态添加控件,以便从viewstate加载选择。在INIT加载应该没问题。

答案 3 :(得分:-1)

DropDownList中的列表项不存储在视图状态中。你必须在每次回发时添加它们。

视图状态中存储的是所选索引 - 即。控制的“价值”。

编辑:嗯,好像我今天学到了一些东西。我的立场得到了纠正: - )

答案 4 :(得分:-1)

我总是使用Page_Load而且从来没有像这样的麻烦。也许你可以看一下。

我通常在第一次加载页面时将数据绑定到控件,之后让Viewstate处理回发等。请注意,他们建议您在Page_Load期间绑定数据...

查看http://support.microsoft.com/kb/305141

页面事件                 loadTOCNode(2,'moreinformation');              在ASP.NET页面的生命周期中,有一些标准事件           经常使用从 Page 对象公开的对象。 ASP.NET页面框架           在运行时自动连接(或连接)适当的委托实例           这些方法的时间。这样您就不必编写必要的“胶水”           代码。“以下列表显示了所连接的委托实例           按照触发顺序运行时间:           
  • Page_Init :在此活动期间,您可以初始化值或连接任何值                 您可能拥有的事件处理程序。
  • Page_Load :在此活动期间,您可以执行一系列操作                 首次创建ASP.NET页面或响应客户端事件                 一个帖子的结果。页面和控件视图状态已恢复                 在此活动之前。使用 IsPostBack 页面属性来检查这是否是第一次                 页面正在处理中。如果是第一次,请执行数据绑定。也,                 读取和更新控件属性。
  • Page_DataBind :在页面调用 DataBind 方法时引发 DataBind 事件水平。如果您在单个控件上调用 DataBind ,它只会触发其下方控件的 DataBind 事件。
  • Page_PreRender PreRender 事件在保存视图状态之前触发                 控件被渲染。您可以使用此事件执行任何最后一分钟                 对控件的操作。
  • Page_Unload :页面渲染完成后, Page_Unload 事件将触发。此活动是进行最终清理的好地方                 工作。这包括清理打开的数据库连接等项目,                 丢弃对象,或关闭那些打开的文件。
以下列表概述了这些事件           不确定性:           
  • Page_Error :如果在页面处理期间发生未处理的异常,则会触发错误事件。 错误事件为您提供了优雅处理的机会                 错误。
  • Page_AbortTransaction 交易事件非常有用,如果您想指明是否有交易                 成功还是失败。此事件通常用于购物车场景                 该事件可以指示订单的成功或失败。这个事件                 在事务中止时触发。
  • Page_CommitTransaction :事件提交时触发此事件                 成功。