Click here to Skip to main content
Licence CPOL
First Posted 8 Oct 2008
Views 33,389
Downloads 663
Bookmarked 29 times

Dynamic Menu Strip

By | 8 Oct 2008 | Article
This article will show you how to create the items (parents and children) in a MenuStrip, dynamically, from a single database table.

Window.PNG

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:

DB_Image.PNG

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)
{
    // Get all root menu items
    var queryResult = (from RootItems in CTX.MenuTables
                       where RootItems.ParentID == null 
                       select RootItems.Item);

    foreach (var item in queryResult)
    {
        // add the root item and check if it has any children
        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)
{
    // Cast the Parent to a ToolStripMenuItem
    ToolStripMenuItem ParentItem = (ToolStripMenuItem)parent;

    // Get the parents ID
    int ID = (from menuItem in CTX.MenuTables
              where menuItem.Item == ParentItem.Text
              select menuItem.ID).First();


    // Get a list of the parents children
    var queryResult = (from menuItem in CTX.MenuTables
                       where menuItem.ParentID == ID
                       select menuItem.Item);

    //if there are any children
    if (queryResult.Count() > 0)
    {
        foreach (var item in queryResult)
        {
            if (item == "-")
            {
                // add a seperator
                ParentItem.DropDownItems.Add(item);
            }
            else
            {
                // add child and check if it has any children
                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 the sender is a ToolStripMenuItem
    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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Harvey Saayman

Software Developer
Osiris Trading
South Africa South Africa

Member

Harvey is in the process of completing his BSc in Information Systems Engineering. He finished the 1st two years in less than a year, he is currently doing the last year part time over two years while working full time as a C# developer. The modules he is currently studying covers business & project management.
 
He is getting his degree from Cambridge university UK, all though hes studying at CTi South Africa.
 
He has been a programmer in professional capacity since Jan 2008, but has been exposed to programming from childhood.
 
He currently works for Uniclox Technologies (Pty) Ltd as the lead project developer. Hes a junior on paper, but more senior developers who has seen his work confirmed that his skill level is way beyond that of a junior.
 
Other interests include music, he has been playing guitar for about four years now. He wishes he can afford a proper 7 string ibanez.
 
Harvey's pet of choice isn't of your common 4 legged variety, he prefers reptiles and currently owns a South African brown house snake and an Australian breaded dragon.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 1 PinmemberEmirian Jaku23:05 12 May '10  
Generaldynamic menu & normal menu same strip Pinmemberravivertis22:17 9 Jul '09  
Generalgood concept PinmemberDonsw14:09 25 Jan '09  
GeneralWhy DB PinmemberSaurabh.Garg19:02 13 Oct '08  
GeneralRe: Why DB PinmemberHarvey Saayman20:18 13 Oct '08  
GeneralSource code link is broken PinmemberTony Bermudez4:53 8 Oct '08  
GeneralRe: Source code link is broken PinmemberHarvey Saayman5:02 8 Oct '08  
QuestionNo Icon or checked menu items? PinmvpJohn Simmons / outlaw programmer4:12 8 Oct '08  
AnswerRe: No Icon or checked menu items? PinmemberHarvey Saayman4:30 8 Oct '08  
AnswerRe: No Icon or checked menu items? PinmemberAndrusM6:58 14 Oct '08  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120517.1 | Last Updated 8 Oct 2008
Article Copyright 2008 by Harvey Saayman
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid