【问题标题】:generate html/asp dynamically动态生成html/asp
【发布时间】:2012-09-18 20:06:16
【问题描述】:

我有一个从表中填充的文件夹/链接的树视图类型结构。我试图做的是通过我的记录集进行程序循环并在 page_init 中生成我的 html,然后尝试绑定控件。当我尝试将链接按钮添加到 html 中的占位符时,它似乎永远找不到它们。

我可能在这里遗漏了一些基本的东西,我见过的所有示例都绑定了页面上已经存在的控件,我无法在 page_init 中自己生成 html 吗?

例子

Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
  content_div.Innerhtml = "<asp:PlaceHolder id=""test"" runat=""server"" ></asp:PlaceHolder>"
End Sub

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
   Dim _linkb As New LinkButton
   _linkb.ID = "lb_cat_" & cat.uID
   _linkb.Attributes.Add("href", "javascript: sltoggle('cat_" & cat.uID & "');")
   _linkb.Attributes.Add("Text", "Expand/Close")
   _linkb.Attributes.Add("runat", "server")
   Dim ph As PlaceHolder = DirectCast(TRIEDEVERYTHINGUNDERTHESUN.FindControl("test"), PlaceHolder)
   ph.Controls.Add(_linkb)
End Sub

如果有人能指出我正确的方向,将不胜感激

问候, 皮特

更新 - 完整代码

Private Sub load_dynamic_file_view()
    Dim _sb As New StringBuilder
    Dim _sfc As New sf_file_category, _sff As New sf_file
    _lsfc = _sfc.get_all_sf_file_category
    _lsff = _sff.get_active_sf_files

    Dim _list_root As List(Of sf_file_category) = _lsfc.FindAll(Function(p) p.parent_id = 0)
    If Not _list_root Is Nothing Then
        _sb.Append("<strong>File Downloads</strong><br />")
        _sb.Append("<div class=""indent-me"" ><br />")
        For Each cat As sf_file_category In _list_root
            'header/Open Link
            Dim _linkb As New LinkButton
            _linkb.ID = "lb_cat_" & cat.uID
            _linkb.Attributes.Add("href", "javascript: sltoggle('cat_" & cat.uID & "');")
            _linkb.Attributes.Add("Text", "Expand/Close")
            _linkb.Attributes.Add("runat", "server")
            Dim ph As PlaceHolder = DirectCast(Me.Master.FindControl("lb_cat_" & cat.uID), PlaceHolder)
            ph.Controls.Add(_linkb)

            _sb.Append(HtmlDecode(cat.name) & " &nbsp;&nbsp;&nbsp;<Asp:PlaceHolder id=""lb_cat_" & cat.uID & """ runat=""server"" /><br />")
            '_sb.Append("<div id=""cat_" & cat.uID & """ class=""toggle-hide"">")
            '_sb.Append(add_child_folder(cat.uID, content))
            '_sb.Append(show_files(cat.uID, content))
            '_sb.Append("</div><div class=""clearfix"" />")
        Next
        _sb.Append("</div>")
        _sb.Append("<br /><br />")
    End If

    content_div.InnerHtml = _sb.ToString
End Sub

Private Function add_child_folder(ByVal catid As Long, ByRef content As ContentPlaceHolder) As String
    Dim _sb As New StringBuilder
    Dim _cl As List(Of sf_file_category) = _lsfc.FindAll(Function(p) p.parent_id = catid)
    If Not _cl Is Nothing Then
        _sb.Append("<div class=""indent-me"" ><br />")
        'For Each _c As sf_file_category In _cl.OrderBy(Function(p) p.view_order)

        _cl.Sort(Function(c1 As sf_file_category, c2 As sf_file_category)
                     Return c1.view_order.CompareTo(c2.view_order)
                 End Function)

        For Each cat As sf_file_category In _cl
            Dim _linkb As New LinkButton
            _linkb.ID = "lb_cat_" & cat.uID
            _linkb.Attributes.Add("href", "javascript: sltoggle(&#39;cat_" & cat.uID & "&#39;);")
            _linkb.Attributes.Add("Text", "Expand/Close")
            _linkb.Attributes.Add("runat", "server")
            Content.Controls.Add(_linkb)

            _sb.Append(HtmlDecode(cat.name) & "&nbsp;&nbsp;&nbsp;<Asp:LinkButton id=""lb_cat_" & cat.uID & """ runat=""server"" Text=""Expand/Close"" href=&#39;javascript: sltoggle(&#39;cat_" & cat.uID & "&#39;);&#39; /><br />")
            '_sb.Append("<div id=""cat_" & cat.uID & """ class=""toggle-hide"">")
            _sb.Append(add_child_folder(cat.uID, content))
            _sb.Append(show_files(cat.uID, content))
            '_sb.Append("</div><div class=""clearfix"" >")
        Next
        _sb.Append("</div><br />")
    End If

    Return _sb.ToString
End Function

Private Function show_files(ByVal catid As Long, ByRef content As ContentPlaceHolder) As String
    Dim _sb As New StringBuilder
    Dim _fl As List(Of sf_file) = _lsff.FindAll(Function(p) p.file_category = catid)
    If Not _fl Is Nothing Then
        _sb.Append("<div class=""indent-me"" ><br />")
        For Each _f As sf_file In _fl
            Dim _linkb As New LinkButton

            _linkb.ID = "file_" & _f.uID
            _linkb.Attributes.Add("onCommand", "download_file")
            _linkb.Attributes.Add("CommandArgument", _f.uID.ToString)
            _linkb.Attributes.Add("Text", _f.file_name)
            _linkb.Attributes.Add("runat", "server")
            AddHandler _linkb.Command, AddressOf download_file
            content.Controls.Add(_linkb)

            _sb.Append("<asp:LinkButton id=""file_" & _f.uID & """ runat=""server"" onCommand=""download_file"" commandArgument=""" & _f.uID & """ Text=""" & _f.file_name & """ /><br />")
        Next
        _sb.Append("</div><br />")
    End If
    Return _sb.ToString
End Function

【问题讨论】:

    标签: asp.net html vb.net


    【解决方案1】:

    您的完整代码显示的是您构建了大量的 HTML 字符串。这对于一些较小的情况很好,但你的代码现在显然变得相当大,我建议你改变这种方法。

    我建议您声明 Web 控件等效项,例如:

    new HtmlGenericControl("div") instead of <div></div>
    

    new HtmlAnchor() OR new LinkButton() instead of <a></a>
    

    在树结构示例中,HTML 可能如下所示:

    <ul>
        <li>
            <a href="root.htm">ROOT</a>
            <ul>
                <li>
                    <a href="levelone">LEVEL 1</a>
                </li>
            </ul>
        </li>
    </ul>
    

    要在代码中生成它,您可以执行以下操作:

    'Menu Holder
    Dim treeStruct As HtmlGenericControl("ul")
    
    'Root
    Dim branch As HtmlGenericControl("li")
    Dim branchItem as HtmlAnchor("a")
    
    'Level 1 
    Dim subLevel As HtmlGenericControl("ul")
    Dim subBranch As HtmlGenericControl("li")
    Dim subBranchItem as HtmlAnchor("a")
    
    'Setup Level 1
    subBranchItem.InnerText = "LEVEL 1"
    subBranchItem.Href = "levelone"
    
    subBranch.Controls.Add(subBranchItem)
    subLevel.Controls.Add(subBranch)
    
    'Setup Root
    branchItem.InnerText = "ROOT"
    branchItem.Href = "root.htm"
    
    'Add Link To Root
    branch.Controls.Add(branchItem)
    'Add Sub Branch To Root
    branch.Controls.Add(subLevel)
    
    treeStruct.Controls.Add(branch)
    

    重要提示以上代码仅用于示例,理想情况下,您可以将功能分离为用于创建分支的函数,然后使用 for 循环遍历您的元素。

    您还会注意到我使用了&lt;UL&gt; 而不是&lt;DIV&gt;,因为我认为树结构是无序列表。此外,您还可以从这种更有棱角的结构中获得造型优势。

    希望对你有帮助

    【讨论】:

    • 谢谢你,下班后我得仔细看看,看看我能去工作:)
    • 嗨,我的这个例子运行良好。我无法完全按照我的老板想要的方式自定义它,所以我必须尝试调整它/尝试其他东西,但我已标记为答案,以便其他人可以使用。再次感谢。
    • 当您需要动态生成如此多的 HTML 时,这是一种恢复结构的好方法。您可以将任何类型的控件放入 .Control.Add() 函数中,因此您始终可以使用 LiteralControl 来为您提供更多自定义。
    【解决方案2】:

    您只生成 HTML 标记而不生成 ASP.Net 标记,因为它们无法被浏览器解析。

    我觉得你的代码应该是这样的

    content_div.Innerhtml = "<div id='test'></div>"
    

    ASP:Placeholder 控件只是一个占位符,它不等于 div HTML 标签。 例如,我在这里给出了 div 标签。

    【讨论】:

      【解决方案3】:

      页面不知道作为文本添加的 asp.net 控件,因此没有为其存储视图状态/对象,因此您永远无法使用 Findcontrol 找到它。

      使用控件的对象并将其添加到父控件的Control集合中 例如

      div.Controls.Add(new PlaceHolder() { ... });
      

      在 Render 事件之前添加它后,它的状态将被保存并可访问。

      【讨论】:

        【解决方案4】:

        看起来您尝试向content_div 添加占位符,但是,您正在做的是将标签呈现为 HTML 内容。

        我不知道content_div到底是什么类型的控件,但你能不能试试:

        content_div.controls.add(new placeholder() { ID = "test" });
        

        这将允许您在 content_div 控件中找到该控件。

        但是,对您来说可能更简洁的解决方案可能如下:

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
           Dim _linkb As New LinkButton
           _linkb.ID = "lb_cat_" & cat.uID
           _linkb.Attributes.Add("href", "javascript: sltoggle('cat_" & cat.uID & "');")
           _linkb.Attributes.Add("Text", "Expand/Close")
           //you don't need this when using code behind
           //_linkb.Attributes.Add("runat", "server")
        
           //this will add your linkbutton to the content_div control
           content_div.Controls.Add(_linkb)
        End Sub
        

        在此之前,您应该会发现它是一种使用 asp 控件动态构建页面的有用方法。

        【讨论】:

        • 我通过 page_init 上的 innerhtml 属性将我的 html 插入到 div 标签中。所以占位符标签应该在 page_load 上的这个 div 内,这是正确的吗?
        • InnerHtml 是一个字符串,它只会呈现为 HTML。如果要添加以后可以使用FindControl 找到的控件,则需要将控件添加到页面,通常在另一个控件或页面本身中。这样做的一种方法是在我的例子中,你试过了吗?
        • 现在试一试 - 我会回复你的 :)
        • 我已经尝试过并让它工作,但它会将它添加到 div 区域的底部,而不是我需要它们的位置,这就是为什么我试图替换html 中的标签 :( 基本上它显示一个带有下载文件链接的动态文件夹结构。我的老板希望它以特定的方式进行样式和组织,所以我需要在文件 ID 中添加大量链接并将事件链接到后面有通用的 file_download 函数。
        • content_div 控件的内容是什么,您是使用代码中的内容还是在页面的.aspx 部分中填充控件?您可以以与上述相同的方式添加PlaceHolder,定义它并将其放入您需要的位置的content_div,如果您以编程方式构建页面,这将起作用,否则您可以将占位符放在您的.aspx 定位正确的位置。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-11
        • 2016-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多