how to use asp repeater with nested bulletedlist p

2019-08-10 07:03发布

问题:

I'm new to using repeaters in vb and I'm trying to understand how to it with a nested bulletedlist programatically. I have the code that generates my data within a System.Web.UI.WebControls.TreeView object and I'm trying to put it into a nested bulletedlist list. I have the following vb and asp code:
TreeView.aspx

<asp:Repeater ID="repeater" runat="server" EnableViewState="False" OnItemDataBound="repeater_ItemDataBound">
    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li>
            <asp:BulletedList ID="bulletedList" runat="server"></asp:BulletedList>
        </li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
</asp:Repeater>

TreeView.aspx.vb

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim tNode As TreeNode
    Dim treeView As New TreeView
    Dim tNodeCollection As New TreeNodeCollection
    tNodeCollection = treeView.Nodes

    ' Code to generate and store within
    ' a System.Web.UI.WebControls.TreeView object
    ' ...
    ' ...
    ' ...

    repeater.DataSource = tNodeCollection          '''<-----UPDATED
    repeater.DataBind()
End Sub

''' UPDATED 
Private Sub searchChildNodes(childNodes As TreeNodeCollection, bList As BulletedList)
    Dim tNode As TreeNode
    For Each tNode In childNodes
        bList.Items.Add(tNode.Value)
        If tNode.ChildNodes.Count > 0 Then
            searchChildNodes(tNode.ChildNodes, bList)
        End If
    Next
End Sub

Ultimately, my goal would produce a nested list as shown below.

<ul>
  <li>My WorkPlace
    <ul>
      <li>Dept 1
        <ul>
            <li>Office
                <ul>
                    <li>Sub-Office</li>
                </ul>
            </li>
        </ul>
      </li>
      <li>Dept 2</li>
      <li>Dept 3</li>
    </ul>
  </li>
</ul>

I can't seem to get this to work. Please let me know what I'm doing wrong and how I can correct my approach.

UPDATE: I've updated my code by correctly specifying the TreeNodeCollection to data bind with the repeater. That being said, I also added a method for OnItemDataBound:

Protected Sub repeater_ItemDataBound(sender As Object, e As RepeaterItemEventArgs)
    Dim tNode As TreeNode
    Dim bList As New BulletedList
    tNode = e.Item.DataItem

    If (tNode Is Nothing) Then
        Return
    End If

    bList = e.Item.FindControl("bulletedList")
    bList.Items.Add(tNode.Text)

    If tNode.ChildNodes.Count > 0 Then
        searchChildNodes(tNode.ChildNodes, bList)
    End If
End Sub

I'm still unable to do nesting with lists. I would ultimately like to achieve the nested lists as referenced above. Please advise so that I may correct my approach.

回答1:

While I would have preferred to use < asp:BulletedList >, I have the solution using HtmlGenericControl, < ul >, < li > :

TreeView.aspx

<asp:Repeater ID="rptr" runat="server" EnableViewState="False" OnItemDataBound="repeater_ItemDataBound">
    <HeaderTemplate>
        <ul>
            <li>My WorkPlace
                <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li id="listItem" runat="server"></li>
    </ItemTemplate>
    <FooterTemplate>
                </ul>
            </li>
        </ul>
    </FooterTemplate>
</asp:Repeater>

TreeView.aspx.vb

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim tNode As TreeNode
    Dim treeView As New TreeView
    Dim tNodeCollection As New TreeNodeCollection
    tNodeCollection = treeView.Nodes

    ' Code to generate and store within
    ' a System.Web.UI.WebControls.TreeView object
    ' ...
    ' ...
    ' ...

    repeater.DataSource = tNodeCollection          '''<-----UPDATED
    repeater.DataBind()
End Sub

Protected Sub repeater_ItemDataBound(sender As Object, e As RepeaterItemEventArgs)
    Dim tNode As TreeNode
    Dim li As New HtmlGenericControl
    Dim ul As New HtmlGenericControl("ul")
    tNode = e.Item.DataItem

    If (tNode Is Nothing) Then
        Return
    End If

    li = e.Item.FindControl("listItem")
    li.ID = tNode.Value
    li.InnerHtml = tNode.Text

    If tNode.ChildNodes.Count > 0 Then
        li.Controls.Add(ul)
        searchChildNodes(tNode.ChildNodes, ul)
    End If
End Sub

Private Sub searchChildNodes(childNodes As TreeNodeCollection, ul As HtmlGenericControl)
    Dim tNode As TreeNode
    For Each tNode In childNodes
        Dim li As New HtmlGenericControl("li")
        li.ID = tNode.Value
        li.InnerHtml = tNode.Text
        ul.Controls.Add(li)
        If tNode.ChildNodes.Count > 0 Then
            Dim unorderedList As New HtmlGenericControl("ul")
            li.Controls.Add(unorderedList)
            searchChildNodes(tNode.ChildNodes, unorderedList)
        End If
    Next
End Sub