I got this idea from helping another member with some similar code. This uses the
Menu Class to build a menu a populates it from a database, allowing for multiple child menus. Sample files are included.
Menu.aspx
Code:
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="menu.aspx.vb" Inherits="_Menu"%>
<html>
<head>
<title>Recursive Menu Example</title>
</head>
<body>
<form id="Form1" runat="server">
<asp:Panel ID="Panel1" runat="server" />
</form>
</body>
</html>
menu.aspx.vb
Code:
Imports System.Data.OleDb
Partial Class _Menu
Inherits System.Web.UI.Page
'//Connection to database from web.config file
Private conn As New OleDbConnection(ConfigurationManager.ConnectionStrings("menu").ConnectionString)
Private Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
Call PopulateMenu()
End Sub
Private Sub PopulateMenu()
Try
'//Define new menu
Dim menu As New Menu()
'//Retrieve menu data
Dim menuData As DataTable = GetMenuData()
AddTopMenuItems(menuData, menu)
Me.Panel1.Controls.Add(menu)
Me.Panel1.DataBind()
Catch ex As Exception
Response.Write(ex.Message.ToString() & "<br />")
End Try
End Sub
Private Function GetMenuData() As DataTable
Try
'//Populate DataTable
Dim strSQL As String = "SELECT * FROM tbl_menu"
Dim datMenu As OleDbDataAdapter = New OleDbDataAdapter(strSQL, conn)
Dim tblMenu As DataTable = New DataTable()
datMenu.Fill(tblMenu)
Return tblMenu
Catch ex As Exception
Response.Write(ex.Message.ToString() & "<br />")
End Try
End Function
Private Sub AddTopMenuItems(ByVal menuData As DataTable, ByVal menu As Menu)
Try
'//Populate DataView
Dim datView As DataView = New DataView(menuData)
'//Filter parent menu items
datView.RowFilter = "parentid = 0"
'//Populate menu with top menu items
Dim datRow As DataRowView
For Each datRow In datView
'//Define new menu item
Dim parentMenu As MenuItem
parentMenu = CreateMenuItem(datRow("linktext"), datRow("linkurl"), datRow("linktext"))
menu.Items.Add(parentMenu)
'//Populate child items of this parent
AddChildMenuItems(menuData, datRow("itemid"), parentMenu)
Next
Catch ex As Exception
Response.Write(ex.Message.ToString() & "<br />")
End Try
End Sub
Private Sub AddChildMenuItems(ByVal menuData As DataTable, ByVal parentID As Integer, Byval parentMenu As MenuItem)
Try
'//Populate DataView
Dim datView As DataView = New DataView(menuData)
'//Filter child menu items
datView.RowFilter = "parentid = " & parentID
'//Populate parent menu item with child menu items
Dim datRow As DataRowView
For Each datRow in datView
'//Define new menu item
Dim childMenu As MenuItem
childMenu = CreateMenuItem(datRow("linktext"), datRow("linkurl"), datRow("linktext"))
parentMenu.ChildItems.Add(childMenu)
'//Populate child items of this parent
AddChildMenuItems(menuData, datRow("itemid"), childMenu)
Next
Catch ex As Exception
Response.Write(ex.Message.ToString() & "<br />")
End Try
End Sub
Private Function CreateMenuItem(ByVal strText As String, ByVal strUrl As String, ByVal strToolTip As String) As MenuItem
Try
'//Create new menu item
Dim menuItem As New menuItem()
'//Set properties of the menu item
With menuItem
.Text = strText
.NavigateUrl = strUrl
.ToolTip = strToolTip
End With
Return menuItem
Catch ex As Exception
Response.Write(ex.Message.ToString() & "<br />")
End Try
End Function
End Class
Untested C# - I haven't tested this as I'm not a C# coder...if anyone has any issues with this, let me know:
Code:
using System.Data.OleDb;
partial class _Menu : System.Web.UI.Page
{
////Connection to database from web.config file
private OleDbConnection conn = new OleDbConnection(ConfigurationManager.ConnectionStrings("menu").ConnectionString);
private void Page_Load(object sender, EventArgs e)
{
PopulateMenu();
}
private void PopulateMenu()
{
try {
////Define new menu
Menu menu = new Menu();
////Retrieve menu data
DataTable menuData = GetMenuData();
AddTopMenuItems(menuData, menu);
this.Panel1.Controls.Add(menu);
this.Panel1.DataBind();
}
catch (Exception ex) {
Response.Write(ex.Message.ToString() + "<br />");
}
}
private DataTable GetMenuData()
{
try {
////Populate DataTable
string strSQL = "SELECT * FROM tbl_menu";
OleDbDataAdapter datMenu = new OleDbDataAdapter(strSQL, conn);
DataTable tblMenu = new DataTable();
datMenu.Fill(tblMenu);
return tblMenu;
}
catch (Exception ex) {
Response.Write(ex.Message.ToString() + "<br />");
}
}
private void AddTopMenuItems(DataTable menuData, Menu menu)
{
try {
////Populate DataView
DataView datView = new DataView(menuData);
////Filter parent menu items
datView.RowFilter = "parentid = 0";
////Populate menu with top menu items
DataRowView datRow = default(DataRowView);
foreach ( datRow in datView) {
////Define new menu item
MenuItem parentMenu = default(MenuItem);
parentMenu = CreateMenuItem(datRow("linktext"), datRow("linkurl"), datRow("linktext"));
menu.Items.Add(parentMenu);
////Populate child items of this parent
AddChildMenuItems(menuData, datRow("itemid"), parentMenu);
}
}
catch (Exception ex) {
Response.Write(ex.Message.ToString() + "<br />");
}
}
private void AddChildMenuItems(DataTable menuData, int parentID, MenuItem parentMenu)
{
try {
////Populate DataView
DataView datView = new DataView(menuData);
////Filter child menu items
datView.RowFilter = "parentid = " + parentID;
////Populate parent menu item with child menu items
DataRowView datRow = default(DataRowView);
foreach ( datRow in datView) {
////Define new menu item
MenuItem childMenu = default(MenuItem);
childMenu = CreateMenuItem(datRow("linktext"), datRow("linkurl"), datRow("linktext"));
parentMenu.ChildItems.Add(childMenu);
////Populate child items of this parent
AddChildMenuItems(menuData, datRow("itemid"), childMenu);
}
}
catch (Exception ex) {
Response.Write(ex.Message.ToString() + "<br />");
}
}
private MenuItem CreateMenuItem(string strText, string strUrl, string strToolTip)
{
try {
////Create new menu item
menuItem menuItem = new menuItem();
////Set properties of the menu item
{
menuItem.Text = strText;
menuItem.NavigateUrl = strUrl;
menuItem.ToolTip = strToolTip;
}
return menuItem;
}
catch (Exception ex) {
Response.Write(ex.Message.ToString() + "<br />");
}
}
}
Table design:
This setup uses a table with the following field types:
itemid - AutoNumber
parentid - Number
linktext - Text
linkurl - Text
Parent items will have parentid = 0 whereas child items will have parentid = itemid of the parent.