-[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.

Setting the DataSource property of a Menu or TreeView to an array

Here is a neat "trick" you can do with the Data controls.  If you have an array of data you want to format, you can just
directly assign it to the Datasource property kind of like this:

 <%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
script runat="server">
   Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
      DataList1.DataSource =
New String() {"one", "two", "three"}
      DataList1.DataBind()
   End Sub
</
script>
<
html xmlns="http://www.w3.org/1999/xhtml" >
   <
head runat="server">
      <title>Untitled Page</title>
   </
head>
<
body>
<form id="form1" runat="server">
<div>
   <asp:DataList ID="DataList1" runat="server">
      <ItemTemplate>
         <%# Container.DataItem %>
      </ItemTemplate>
   </asp:DataList>
</div>
</form>
</
body>
</
html>

However, if you've ever tried this with the Menu or Treeview, you'd quickly figure out it doesn't work.  This is
because the HierarchicalDataSourceView requires a new type called a IHierarchicalEnumerable which enumerates
a type called IHierarchyData.  The solution would be to implement these two interfaces as minimally as possible.

 

 Public Class HierarchicalData
   Implements IHierarchicalEnumerable



   
Private data As ArrayList
   Public Sub New(ByVal values() As String)
      data =
New ArrayList()
      For Each value As String In values
         data.Add(
New HierarchicalDataElement(value))
      Next
   End Sub

   Public
Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
      Return data.GetEnumerator()
   End Function
   Public Function GetHierarchyData(ByVal enumeratedItem As Object) As System.Web.UI.IHierarchyData Implements System.Web.UI.IHierarchicalEnumerable.GetHierarchyData
      Return CType(enumeratedItem, HierarchicalDataElement)
   End Function
End
Class


Public
Class HierarchicalDataElement
   Implements IHierarchyData    
   
Public _data As String
   Public Sub New(ByVal data As String)
      _data = data
   End Sub
   Public Function GetChildren() As System.Web.UI.IHierarchicalEnumerable Implements System.Web.UI.IHierarchyData.GetChildren
      Return Nothing
   End Function
   Public Function GetParent() As System.Web.UI.IHierarchyData Implements System.Web.UI.IHierarchyData.GetParent
      Return Nothing
   End Function
   Public ReadOnly Property HasChildren() As Boolean Implements System.Web.UI.IHierarchyData.HasChildren
   Get
      Return False
   End Get
   End Property
   Public ReadOnly Property Item() As Object Implements System.Web.UI.IHierarchyData.Item
   Get
      Return _data
   End Get
   End Property
   Public ReadOnly Property Path() As String Implements System.Web.UI.IHierarchyData.Path
   Get
      Return _data
   End Get
   End Property
   Public ReadOnly Property Type() As String Implements System.Web.UI.IHierarchyData.Type
   Get
      Return _data.GetType().ToString()
   End Get
   End Property
   
    Public
Overrides Function ToString() As String
       Return _data
    End Function
End
Class
 

And to use it, declare a Menu on your form and just add the following code.  There is no need to bind to
Container.DataItem in a template because the MenuItems get their text value from the IHierarchyData.ToString() overload. 

 

<script runat="server">
   Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
      Menu1.DataSource = New HierarchicalData(New String() {"one", "two", "three"})
      Menu1.DataBind()
   End
Sub
</
script
>

Comments

Josh Rogers said:

This is great, but can you expand upon this more....for instance if instead of an array you were using a menuitemcollection

It seems with this it is much more complicated as you have to build the hierarchicaldatasourceview and hierarchicaldatasource to be able to bind it to the menu, if you want to have full functionality...anywhere you know of that has an implementation of this, or could you give me a nudge in the right direction....
# December 22, 2005 2:13 PM

Danny Chen said:

Josh,
The HierarchicalDataBoundControl requires that the DataSource be either an IHierarchicalEnumerable or an IHierarchicalDataSource. The MenuItemCollection is an ICollection so you could not bind an arbitrary HierarchicalDataBoundControl (Menu, TreeView, or other) to a MenuItemCollection.

However, if you desired to use a MenuItemCollection as the base storage mechanism for your data, you could create your own classes implementing these two interfaces as I've shown above and fill out the required functions with respect to a MenuItemCollection. You should be able to use the enumerator for the ICollection in the IHierarchicalEnumerable. You can pass in the enumerated item to the IHierarchyData class (perhaps created dynamically inside GetHierarchyData). The MenuItem should contain all the information you need to fill in the necessary interfaces.
--
Danny
# December 22, 2005 2:31 PM

Could you please post the example in c# as well said:

Could you please post the example in c# as well
# January 3, 2006 2:43 PM

Danny Chen said:

# January 3, 2006 3:55 PM

ppayal said:

Hi Danny,

I found this article helpful. Can you please tell me the following:

I have used a string array e.g array of alphabets from a to z. I assign it to a datalist control. Now I want that when he clicks on 'd' there should be a postback and all names starting with letter 'd' are displayed in dropdownlist.

Can you please help me?

Regards,

ap.

# January 23, 2007 8:01 AM

Olivia BENNETT said:

Undoubtfully nice story u got here. It would be great to read a bit more concerning this theme. Thanx for posting that info.

Olivia BENNETT

<a href=" www.renttobuyguide.co.uk/">rent to buy guide</a>

# April 29, 2010 3:35 AM

Summer Cook said:

Really great blog u got here. It would be great to read something more about such topic. Thanks for posting that info.

Summer Cook

<a href="www.waybiz.com/">Find suppliers</a>

# May 4, 2010 5:41 PM

Joan Hakkinen said:

Rather nice place you've got here. Thanks for it. I like such topics and everything that is connected to this matter. I would like to read a bit more soon.  

Joan Hakkinen    

<a href="www.pickescort.com/">escorts private</a>

# April 27, 2011 4:11 PM

weblogs.asp.net said:

432382.. Ho-o-o-o-t :)

# May 28, 2011 11:47 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)