
Introduction
Recently, I needed to populate a MenuStrip on the fly when my application starts up. The reason for this is to be able to hide functionality depending on what kind of license the end users purchased. The menus will be defined in a single DB table which will be populated by the installer.
Background
The DB table is as follows:

We have an ID which is an IDENTITY(0, 1) field, the Item field will be the text displayed in the MenuStrip, and the ParentID field is the ID of the item's parent - if it is a root item (the item has no parent), the field is left blank or assigned a NULL. To achieve a separator, the Item field must be a "-".
Using the code
The first thing we need to do is query the table to find all the root menu items, these will be the items with a NULL value in the ParentID column. I've queried my DB using LINQ. Here is my OnFormLoad event handler:
private void FrmMain_Load(object sender, EventArgs e)
{
var queryResult = (from RootItems in CTX.MenuTables
where RootItems.ParentID == null
select RootItems.Item);
foreach (var item in queryResult)
{
AddChildMenuItems(menuStrip.Items.Add(item, null,
new EventHandler(MenuItemClicked)));
}
}
After the root items are queried, we foreach the result to add them to the MenuStrip. Notice that the MenuStrip.Items.Add() method returns a ToolStripItem, this is the item that has just been added. We will send this to the AddChildMenuItems() method to check if the item has children, and if there are, add them to the menu.
private void AddChildMenuItems(ToolStripItem parent)
{
ToolStripMenuItem ParentItem = (ToolStripMenuItem)parent;
int ID = (from menuItem in CTX.MenuTables
where menuItem.Item == ParentItem.Text
select menuItem.ID).First();
var queryResult = (from menuItem in CTX.MenuTables
where menuItem.ParentID == ID
select menuItem.Item);
if (queryResult.Count() > 0)
{
foreach (var item in queryResult)
{
if (item == "-")
{
ParentItem.DropDownItems.Add(item);
}
else
{
AddChildMenuItems(ParentItem.DropDownItems.Add(item,
null, new EventHandler(MenuItemClicked)));
}
}
}
}
Here, the first thing we do is get the parent item's ID with another LINQ query. After that, we query the DB to get a list of the item's children (if any). If the second query has any rows, we foreach the results. In the foreach, we first check if the item is a separator, which is represented by a "-"; if it is, we simply add it to its parent. If it is not a separator, we add the item to its parent, and call the AddChildMenuItems() method with its return value to see if it has any children.
Notice that the root and child items all take a new EventHandler(MenuItemClicked) as a parameter, this is the method that gets executed if any of these items are clicked. The code for this method follows...
private void MenuItemClicked(object sender, EventArgs e)
{
if (sender.GetType() == typeof(ToolStripMenuItem))
{
string ClickedItemText = ((ToolStripItem)sender).Text;
listBox1.Items.Add(ClickedItemText);
switch (ClickedItemText)
{
case "Exit":
Application.Exit();
break;
}
}
}
First, we confirm that the sender object is in fact a ToolStripMenuItem; if it is, we get the text of this item and save it in a string variable (this is only done to improve readability). In my handler, the item is added to a list box to confirm that it has been clicked.
After that, we use a switch statement so that we can individually handle the clicked items. I added a "handler" for exit, so if the clicked item is "exit", the application will close.