【问题标题】:Dynamically created DropDownList loses ListItems on Postback动态创建的 DropDownList 在回发时丢失 ListItems
【发布时间】:2009-03-08 13:56:29
【问题描述】:

我有一个页面,其中包含一些动态创建的控件(TextBox 和 DropDownList)。当回发发生时,TextBox 会保留它们的值,但 DropDownList 会丢失它们的 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>

【问题讨论】:

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


    【解决方案1】:

    我找到了允许我在回发中保持视图状态的解决方案。 就是调用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>
    

    【讨论】:

      【解决方案2】:

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

      您的代码和标记中包含所有这些视图状态语句,这让我感到很高兴。

      发生了几件事:

      1. 控件的 ViewState 被禁用
      2. 控件层次结构上方的 ViewState 已禁用(页面、表单、面板)
      3. 您在页面周期中动态添加控件为时已晚,无法从视图状态加载选择。在 INIT 中加载应该没问题。

      【讨论】:

      • 我添加了 EnableViewState 用于测试目的。由于 ddlFixed 保持其状态,因此面板和 Ddls 也应如此。将创建移动到 PreInit 或 Load 也无济于事。我很困惑……
      • 为什么要对视图状态进行所有操作?尝试使用所有默认值。
      • 谢谢。这个想法是不鼓励“尝试启用视图状态”cmets。我开始时没有所有 EnableViewStates,然后它也不起作用。
      • 你为什么不添加你的@page指令以便我们可以看到它
      【解决方案3】:

      您可能需要为那些 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>
      

      【讨论】:

      • 列表视图项没有 viewstate 属性。您只能在 DDL 上操作视图状态。
      • 谢谢安德鲁...我在考虑我当前的编码并说 ListView... 甚至不相关:)
      • 谢谢。但我已经将动态创建的 DDL 上的 EnableViewState 显式设置为 True。
      • @schudel:我总是第一次在 OnPageLoad 上执行加载逻辑。可能是面板正在修改您的设置? (我从来没有在我的 ASP.net 项目中使用过面板......)
      • @Romias:我尝试将控件直接添加到表单中:结果相同。尝试过加载:相同的结果。
      【解决方案4】:

      我总是使用Page_Load,从来没有遇到过这样的麻烦。也许你可以看看。

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

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

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

      【讨论】:

      • 谢谢。不幸的是,这不会改变行为。
      【解决方案5】:

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

      视图状态中存储的是选定的索引 - 即。控件的“值”。

      编辑:好吧,看来我今天学到了一些东西。我的立场是正确的:-)

      【讨论】:

      • 谢谢。那么为什么要重新创建 ddlFixed 项目,尽管我没有在回发周期中添加它们?
      • 不正确。 ddl 项目在视图状态中维护。它们只需要在初始加载期间添加。
      猜你喜欢
      • 2010-11-21
      • 2013-03-23
      • 2019-11-02
      • 1970-01-01
      • 2015-01-17
      • 1970-01-01
      • 1970-01-01
      • 2014-09-27
      • 1970-01-01
      相关资源
      最近更新 更多