【问题标题】:Dynamically adding listitems to a select tag in ASP.NET将列表项动态添加到 ASP.NET 中的选择标记
【发布时间】:2013-11-23 08:47:42
【问题描述】:

我正在尝试做一些我认为非常简单的事情 - 使用 ASP.NET 在选择标记中动态添加一些选项。

我的代码写成:

<select id='cmbDuration'>
<%  Dim periods As Generic.List(Of Models.Duration) = DBSupport.getDurations
    For Each d As Models.Duration In periods
        Response.Write("<option value='" & d.id & "'>" & d.name & "</option>")        
    Next   
 %>
</select>

一切正常,我的 db 层返回的数据出现在我的选择标签中。

后来,我记得添加了一个runat = "Server" 标签,以便在我的代码隐藏帖子中处理我的数据。但是,添加之后,不会显示任何选项。检查生成的源代码,我也没有看到添加任何选项。

这里有什么问题?为什么添加runat = "Server"时不显示选项?

【问题讨论】:

  • 你应该使用asp:DropDownList
  • 这是可以理解的,但是,即使asp:DropDownList 被渲染为select 标签,为什么添加runat="Server" 会导致循环内的代码不会在页面上渲染任何内容?跨度>
  • 您不能像现在这样将 runat="server" 添加到呈现的控件中。你应该把它想象成你只是渲染了一堆字符串(HTML),这发生在解析 runat="server" 标记之后。因此,您可以添加一个 runat="server" 标记,然后在后面的代码中添加选项,或者您可以添加一个 HTML 负载,这在后面的代码中不可用。你不能两者都做,这是你想要做的。
  • 所以,我理解这一点的方式是,添加 runat="Server" 属性将导致我的控件仅在代码隐藏中可用于后续进程。我尝试了以下方法,这证明了这一点:&lt;input type="checkbox" id="myId" runat="server"/&gt;&lt;% myId.Checked = True%&gt; - 代码块被忽略,复选框保持未选中状态。我必须在代码隐藏中更改其检查状态。谢谢。
  • 添加了更具描述性的答案。这是关于编译时和运行时的差异。

标签: html asp.net forms html-select


【解决方案1】:

所以,我理解这一点的方式是添加 runat="Server" 属性将导致我的控件可用于后续 仅在代码隐藏中处理

不,添加 runat="server" 会告诉 Visual Studio 和编译器此控件将表示为服务器控件。它将服务器控件添加到您的 .designer.cs 文件中:

 /// <summary>
 /// Image3 control.
 /// </summary>
 /// <remarks>
 /// Auto-generated field.
 /// To modify move field declaration from designer file to code-behind file.
 /// </remarks>
 protected global::System.Web.UI.WebControls.Image Image3;

这个过程发生在设计时

您的代码(&lt;%%&gt; 中的所有内容)发生在运行时。因此,您尝试使用代码块构建动态 HTML。所以设计师不知道你要添加什么,你要添加多少控件?我如何表示这个? 所以它无法构建服务器端控制代码。所以它没有。它还会导致运行时代码无法处理ViewState。同样,它不知道您的控件应该代表什么。

所以你不能简单地:

<select id='cmbDuration' runat='server'>
<%  Dim periods As Generic.List(Of Models.Duration) = DBSupport.getDurations
    For Each d As Models.Duration In periods
        Response.Write("<option value='" & d.id & "' runat='server'>" & d.name & "</option>")        
    Next   
 %>
</select>

这只是无效的 ASP.Net 语法。您不能以这种方式在 runtime 写入后面的代码。在执行你的 for 循环之前,.Net 已经构建了它需要的块后面的代码,所以你不能添加到这个。

我不会重复@Scott 已经回答的内容,但这是您需要做的。

【讨论】:

  • 感谢您的澄清。
【解决方案2】:

您为什么要在代码隐藏帖子中讨论处理数据,而要编写内联代码来生成列表项?您应该在代码隐藏中绑定您的下拉列表:

ASP.NET

<asp:DropDown ID="cmbDuration" DataTextField="Name" DataValueField="ID" runat="server" />

代码隐藏(在 Page_Load 中)

If Not Page.IsPostBack Then
    Dim periods As Generic.List(Of Models.Duration) = DBSupport.getDurations
    cmbDuration.DataSource = periods
    cmbDuration.DataBind()
End If

【讨论】:

  • 你当然是对的,我只是想知道为什么添加runat="server" 属性会导致我在循环中的代码根本不被执行。 Liam 的评论帮助我更好地理解了这一点。
【解决方案3】:

问题是您正在使用函数 Response.Write() 写入 ASPNET 的“响应流”,这将导致输出选项标签出现在打印响应流的页面的最顶部.这甚至会出现在 HTML 声明标记的上方。 (检查您的 HTML 源代码以查看)如果您希望将输出直接写入 ASPX 页面,请尝试以下操作:

<select id='cmbDuration'>
    <%For x As Integer = 0 To 5%>
        <option><%=x%></option>
    <%Next%>
</select>

如果有帮助,请告诉我!

【讨论】:

  • 谢谢。我不认为使用Response.Write 是问题——我在循环内使用建议的&lt;%For x As Integer = 0 To 5%&gt;Response.Write("&lt;option&gt;" &amp; n.ToString &amp; "&lt;/option&gt;") 进行了测试,两种方法都有效。只要添加了runat="server",它们都不会。
  • 为了记录,我确实在代码隐藏中添加了添加列表项的代码,当然它有效,但我仍然不明白最初的问题。
  • 当我添加 runat="server" 时,这会在 VS2012 中产生编译错误(我绑定了框架 2.0、3.5 和 4.5)。 runat="server" 控件不支持代码块。
  • 我还在用VS2008。
  • 我有多个版本的VS。我尝试了 2008 年、2010 年和 2012 年。都给我以下编译错误:“此上下文中不支持代码块。”对不起,我也帮不上忙。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
  • 2019-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多