There have been several posts asking for help to populate the menu items from a database. I have done this with an unlimited number of submenus. Below is my solution.
NOTE: In the code below is a class named "Database". This is a class I wrote to connect to the database with several methods such as pull a SQL statement from the database, retrieve a scalar value, and to return a DataReader. You will need to modify the code to replace these functions.
First the table. (SQL Server 2000 T-SQL Script)
/****** Object: Table [dbo].[APP_Menu] Script Date: 2/1/2005 11:06:31 AM ******/
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[APP_Menu]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[APP_Menu]
GO
/****** Object: Table [dbo].[APP_Menu] Script Date: 2/1/2005 11:06:31 AM ******/
CREATE TABLE [dbo].[APP_Menu] (
[ID] [numeric](18, 0) IDENTITY (1, 1) NOT NULL ,
[Text] [nvarchar] (25) NOT NULL ,
[ToolTip] [nvarchar] (255) NULL ,
[ImgLeft] [varchar] (50) NULL ,
[ImgRight] [varchar] (50) NULL ,
[Url] [varchar] (255) NULL ,
[DisplayOrder] [numeric](18, 0) NOT NULL ,
[ParentID] [numeric](18, 0) NOT NULL ,
[Display] [bit] NOT NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[APP_Menu] WITH NOCHECK ADD
CONSTRAINT [PK_APP_Menu] PRIMARY KEY CLUSTERED
(
[ID]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[APP_Menu] ADD
CONSTRAINT [DF_APP_Menu_DisplayOrder] DEFAULT (0) FOR [DisplayOrder],
CONSTRAINT [DF_APP_Menu_ParentID] DEFAULT (0) FOR [ParentID],
CONSTRAINT [DF_APP_Menu_Display] DEFAULT (1) FOR [Display]
GO
Columns
------------- ----------------
ID Just an ID for the row. (Identity)
Text The text to display for the MenuItem.
ToolTip The ToolTip property value for the MenuItem.
ImgLeft The path and filename for an image to display to the left of the text for the MenuItem. (i.e. ./img/bullet.gif)
ImgRight The path and filename for an image to display to the right of the text for the MenuItem. (i.e. ./img/RightArrow.gif)
Url The Url property value for the MenuItem.
DisplayOrder This is a numeric value for the display order on the menu.
ParentID The ID of the parent MenuItem. For the main menu the value is 0.
Display This allows menus to be removed without removing the row from the database table.
Sample Data
ID Text ToolTip ImgLeft ImgRight Url DisplayOrder ParentID Display
--- ----------------------- ---------- ---------- ----------------------- ---------------------------------- --------------- ---------- -------
1 Home NULL NULL NULL http://www.teelsys.com/ 0 0 1
2 Search Engines NULL NULL NULL NULL 1 0 1
3 Google NULL NULL NULL http://www.google.com/ 0 2 1
4 Yahoo NULL NULL NULL http://www.yahoo.com/ 1 2 1
5 News NULL NULL NULL NULL 2 0 1
6 CNN NULL NULL NULL http://www.cnn.com/ 0 5 1
7 MSNBC NULL NULL NULL http://www.msnbc.com/ 1 5 1
8 Weather NULL NULL ./img/menuRArrow.gif NULL 2 5 1
9 Weather Channel NULL NULL NULL http://www.weather.com/ 0 8 1
10 Weather Underground NULL NULL NULL http://www.weatherunderground.com/ 1 8 1
Diagram of the menu
Home
Search Engines ___ Google
|_ Yahoo
News _____________ CNN
|_ MSNBC
|_ Weather ___ Weather Channel
|_ Weather Underground
The BaseSQL used in the code below.
SELECT (CASE WHEN ImgLeft IS NULL THEN '' ELSE '
' END) + [Text] +
(CASE WHEN ImgRight IS NULL THEN '' ELSE '
' END) AS [Text],
ISNULL(ToolTip, '') AS ToolTip,
ISNULL(Url, '') AS Url,
[ID],
(SELECT COUNT(*) FROM APP_Menu B WHERE B.ParentID = A.ID) AS SubMenuItemsCount
FROM APP_Menu A
WHERE Display = 1
AND ParentId = @ParentID
ORDER BY ParentID, DisplayOrder
The sample code below uses recursion to buid the submenus.
NOTE: In the code below is a class named "Database". This is a class I wrote to connect to the database with several methods such as pull a SQL statement from the database, retrieve a scalar value, and to return a DataReader. You will need to modify the code to replace these functions.
namespace kod3web.controls
{
using System;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using kod3web.classes;
using System.Data.SqlClient;
///
/// Summary description for Menu.
///
public class Menu : System.Web.UI.UserControl
{
protected skmMenu.Menu mnuMain;
protected System.Web.UI.WebControls.Panel panMenu;
private void LoadSubMenu(skmMenu.MenuItem oParentMenuItem, string BaseSQL,
long ParentID)
{
Database oDB = new Database();
string SQL = BaseSQL.Replace("@ParentID", ParentID.ToString());
SqlDataReader oDataReader = oDB.GetData(SQL);
skmMenu.MenuItem oMenuItem = null;
int iOrdinal = -1;
long myID = 0;
while(oDataReader.Read())
{
oMenuItem = new skmMenu.MenuItem();
iOrdinal = oDataReader.GetOrdinal("Text");
oMenuItem.Text = oDataReader.GetString(iOrdinal);
iOrdinal = oDataReader.GetOrdinal("ToolTip");
oMenuItem.ToolTip = oDataReader.GetString(iOrdinal);
iOrdinal = oDataReader.GetOrdinal("Url");
oMenuItem.Url = oDataReader.GetString(iOrdinal);
iOrdinal = oDataReader.GetOrdinal("ID");
myID = long.Parse(oDataReader.GetValue(iOrdinal).ToString());
iOrdinal = oDataReader.GetOrdinal("SubMenuItemsCount");
if(oDataReader.GetInt32(iOrdinal) > 0)
{
LoadSubMenu(oMenuItem, BaseSQL, myID);
}
oParentMenuItem.SubItems.Add(oMenuItem);
}
oDB = null;
}
private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
Database oDB = new Database();
string baseSQL = oDB.GetSQLFromQueryName("MenuItems");
string SQL = baseSQL.Replace("@ParentID", "0");
SqlDataReader oDataReader = oDB.GetData(SQL);
skmMenu.MenuItem oMenuItem = null;
int iOrdinal = -1;
long myID = 0;
while(oDataReader.Read())
{
oMenuItem = new skmMenu.MenuItem();
iOrdinal = oDataReader.GetOrdinal("Text");
oMenuItem.Text = oDataReader.GetString(iOrdinal);
iOrdinal = oDataReader.GetOrdinal("ToolTip");
oMenuItem.ToolTip = oDataReader.GetString(iOrdinal);
iOrdinal = oDataReader.GetOrdinal("Url");
oMenuItem.Url = oDataReader.GetString(iOrdinal);
iOrdinal = oDataReader.GetOrdinal("ID");
myID = long.Parse(oDataReader.GetValue(iOrdinal).ToString());
iOrdinal = oDataReader.GetOrdinal("SubMenuItemsCount");
if(oDataReader.GetInt32(iOrdinal) > 0)
{
LoadSubMenu(oMenuItem, baseSQL, myID);
}
mnuMain.Items.Add(oMenuItem);
}
mnuMain.CssClass = "menustyle";
mnuMain.HighlightTopMenu = true;
mnuMain.Opacity = "100";
mnuMain.zIndex = 1000;
mnuMain.Cursor = skmMenu.MouseCursor.Pointer;
oDB = null;
}
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
}
}