1

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.

usr4896260
  • 1,427
  • 3
  • 27
  • 50
  • 1
    There doesn't seem to be a data source specified for your repeater, so `repeater.DataBind()` may be redundant (in fact, it may be clearing your repeater). Also, I'm not sure if a bulleted list control supports nesting. [This answer](http://stackoverflow.com/a/3571468/5233918) discusses nesting repeaters, and a quick search shows that there are several approaches to rendering tree views as unordered lists (haven't tried them though). – Michael McMullin Dec 03 '15 at 17:03
  • You are correct Michael. repeater.DataBind() was clearing the repeater and after removing it, the lists load now (It is not nested however). Also yes, bulletedlist don't support nesting natively, which is why I chose to go with repeaters as suggested [here](http://stackoverflow.com/a/23429681/4896260). My main concern is to get the nested lists, which at the moment I can't get to work. – usr4896260 Dec 03 '15 at 19:46

1 Answers1

0

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
usr4896260
  • 1,427
  • 3
  • 27
  • 50