In my last post I showed you a workaround that allowed you to create a horizontal submenu when you clicked on a MenuItem from another menu on the same page. That example hard-coded the MenuItem definitions into the code file, and I said that I’d be demonstrating how to create a horizontal submenu from a sitemap file. While attempting this, I got hit in the face by an error that has to do with hierarchy which I researched only to find that most people suggest it would be easier to find another alternative rather than try to solve the problem.
My alternative was to create a custom xml file that contains property definitions for the MenuItem class (namely Text and NavigateURL). Here it is:
|1||<?xml version=“1.0” encoding=“utf-8” ?>|
Unfortunately, here’s where the frustration kicked in (mostly because I have very little experience working with XML). I had a lot of problems figuring out how to get the right values out of the XML and into my menu where I needed them. Good thing for you, I’ve spared you the aggravation by fighting through it for you.
Basically, we need to select each <name> and <url> element outlined in the XML and use the text inside of those as our menu definition properties. It took a few hours, but I managed it; here’s how:
|3||Protected Sub Menu1_ItemClick(ByVal sender As Object, ByVal e As System.WebUI.WebControls.MenuEventArgs) Handles Menu1.MenuItemClick|
Select Case e.Item.Value.ToString
Dim doc As New XmlDocument
Dim NameNodes As XmlNodeList = doc.SelectNodes(“/CategoriesMenu/item/name”)
Dim URLNodes As XmlNodeList = doc.SelectNodes(“/CategoriesMenu/item/url”)
If NameNodes.Count = URLNodes.Count Then
For i As Integer = 0 To NameNodes.Count – 1
Dim m As New MenuItem
m.Text = NameNodes.Item(i).FirstChild.InnerText
m.NavigateUrl = URLNodes.Item(i).FirstChild.InnerText
What we’re doing here is opening the XML document that contains the defined structure for our menu (see XML sample above), and we’re selecting the XML Nodes in that document that match our XPath Expressions (namesly “/Categories/item/name”)
Once we have those collections, we need to check to make sure that both collections have the same amount of elements in them. We do this to avoid adding a menu item that doesn’t have a URL attached to it (which might happen if you get distracted while working on the XML).
If both collections have the same amount of elements, we know that the XML is valid (for our purposes at least), and we create a new menu item in our sub menu for each element in the collections.
All of this goes into a Select Case … End Select Statement to eliminate confusion in the case of multiple sub menus.
You could also use just the 1 XML file for all sub menus. Just replace the <CategoriesMenu></CategoriesMenu> element with the something else (<ProductsMenu></ProductsMenu> for instance). Remember, too, to add another Case to your select for the Products menu.
So, there you have it: A quick workaround to creating a horizontal submenu in asp.NET using XML as a data source.
It’s not as clean as it probably can be, but that’s what you get for teaching yourself code…
Until next time!