-[Danny Chen]- Blog of an ASP.NET QA tester

Tips and info about Site Navigation, ImageMap, Menu and other cool ASP.NET v2.0 features.

Code Listing for 12/19/05 (VB)

RecursiveULMenu.vb

Imports Microsoft.VisualBasic
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Collections
Imports System.Collections.Generic
Imports System.ComponentModel

Namespace My

    Public Class RecursiveULMenu
        
Inherits HierarchicalDataBoundControl

        
' Template Declarations
        Private _HeaderTemplate As ITemplate
        
Private _FooterTemplate As ITemplate
        
Private _ItemTemplate As ITemplate
        
Private _ItemHeaderTemplate As ITemplate
        
Private _ItemFooterTemplate As ITemplate

        <PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(
GetType(MyDataItem))> _
        
Public Property HeaderTemplate() As ITemplate
            
Get
                Return _HeaderTemplate
            
End Get
            Set(ByVal value As ITemplate)
                _HeaderTemplate = value
            
End Set
        End Property

        <PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(GetType(MyDataItem))> _
        
Public Property FooterTemplate() As ITemplate
            
Get
                Return _FooterTemplate
            
End Get
            Set(ByVal value As ITemplate)
                _FooterTemplate = value
            
End Set
        End Property

        <PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(GetType(MyDataItem))> _
        
Public Property ItemTemplate() As ITemplate
            
Get
                Return _ItemTemplate
            
End Get
            Set(ByVal value As ITemplate)
                _ItemTemplate = value
            
End Set
        End Property

        <PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(GetType(MyDataItem))> _
        
Public Property ItemHeaderTemplate() As ITemplate
            
Get
                Return _ItemHeaderTemplate
            
End Get
            Set(ByVal value As ITemplate)
                _ItemHeaderTemplate = value
            
End Set
        End Property

        <PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(GetType(MyDataItem))> _
        
Public Property ItemFooterTemplate() As ITemplate
            
Get
                Return _ItemFooterTemplate
            
End Get
            Set(ByVal value As ITemplate)
                _ItemFooterTemplate = value
            
End Set
        End Property

        ' Field to find the data value from
        Public Property TextField() As String
            Get
                Dim o As Object = ViewState("TextField")
                
If o Is Nothing Then
                    Return String.Empty
                
Else
                    Return CType(o, String)
                
End If
            End Get
            Set(ByVal value As String)
                ViewState(
"TextField") = value
            
End Set
        End Property

        Protected Overrides Sub CreateChildControls()
            RecursiveCreateChildControls(GetData(
"").Select())
        
End Sub

        Private Sub RecursiveCreateChildControls(ByVal dataItems As IHierarchicalEnumerable)
            
Dim firstItem As Boolean = True
            For Each e As Object In dataItems

                
' Render the header only if we have child items
                If firstItem Then
                    Dim header As New MyDataItem(String.Empty)
                    HeaderTemplate.InstantiateIn(header)
                    Controls.Add(header)
                    firstItem =
False
                End If

                Dim data As IHierarchyData = dataItems.GetHierarchyData(e)

                
' Find the data value based on the TextField
                Dim text As String = String.Empty
                text = DataBinder.GetPropertyValue(data, TextField)

                
' Create an item header
                Dim itemHeader As New MyDataItem(String.Empty)
                ItemHeaderTemplate.InstantiateIn(itemHeader)
                Controls.Add(itemHeader)
                itemHeader.DataBind()

                
' Create the data item
                Dim item As New MyDataItem(text)
                ItemTemplate.InstantiateIn(item)
                Controls.Add(item)
                item.DataBind()

                
' Create any child items
                RecursiveCreateChildControls(data.GetChildren())

                
' Create the item footer
                Dim itemFooter As New MyDataItem(String.Empty)
                ItemFooterTemplate.InstantiateIn(itemFooter)
                Controls.Add(itemFooter)
                itemFooter.DataBind()

            
Next

            ' If we had a header, then render out the footer
            If firstItem = False Then
                Dim footer As New MyDataItem(String.Empty)
                FooterTemplate.InstantiateIn(footer)
                Controls.Add(footer)
            
End If
        End Sub

    End Class

    ' In most applications the DataItem and the container should be separated into
    ' two classes, in this case, I've collapsed them into itself since I only have
    ' one data property.  
    Public Class MyDataItem
        
Inherits Control
        
Implements INamingContainer
        
Implements IDataItemContainer

        
' The item data
        Private _text As String
        Public ReadOnly Property Text() As String
            Get
                Return _text
            
End Get
        End Property

        Public Sub New(ByVal Text As String)
            _text = Text
        
End Sub

        Public ReadOnly Property DataItem() As Object Implements System.Web.UI.IDataItemContainer.DataItem
            
Get
                Return Me
            End Get
        End Property

        Public ReadOnly Property DataItemIndex() As Integer Implements System.Web.UI.IDataItemContainer.DataItemIndex
            
Get
                Return 0
            
End Get
        End Property

        Public ReadOnly Property DisplayIndex() As Integer Implements System.Web.UI.IDataItemContainer.DisplayIndex
            
Get
                Return 0
            
End Get
        End Property
    End Class

End
Namespace

 

Posted: Dec 19 2005, 09:10 AM by dannychen | with 1 comment(s)
Filed under:

Comments

Danny117 said:

Hope this is what I'm looking for.  Last source I listed was just li no hiarchy.   Here's what I'm going to do with it.  I'm going to transform the bloatware asp.net menu into a ul li list then use the jquery droppy plugin to display it.

# February 5, 2009 3:15 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)