Click here to Skip to main content
15,884,836 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hey Guys, I need a little help with something I am trying to do. Basically I want to recursively build a list of menu items.

So my Menu class is as follows

C#
short MenuId {get; set;}
string MenuName { get; set;}
string Url {get; set;}
short ParentmenuId { get set;}
List<menu> SubMenus {get; set;}
</menu>


So as you can see each Menu item can have submenus, I populate my original list with all menus from the database, so I'm just wondering how to loop through this list building the menu structure and add all the submenus to the list of sub-menus belonging to each parent.

I hope I'm being clear. thanks guys
Posted
Comments
Mohammed Nabeel Khan 26-Jun-14 17:29pm    
well why do you need recursion?

Here's the version with two different classes for menu and menu selection. You should be able to just grab the whole block, past it into a form and run it in order to see it in action.

#region Example4b - Menu
public static void Example4b()
{
    using (Form form = new Form())
    {
        form.Menu = CreateMainMenu4b();
        MenuParent parent = CreateMenuInfos4b();
        foreach (MenuSelection info in parent.list)
        {
            BuildMenus4b(info, form.Menu, null);
        }
        form.ShowDialog();
    }
}
private static MainMenu CreateMainMenu4b()
{
    MainMenu menu = new MainMenu();
    return menu;
}
private static MenuParent CreateMenuInfos4b()
{
    EventHandler handler;

    MenuParent parent = new MenuParent();
    parent.list = new List<MenuSelection>();
    /////// stuff
    parent.list.Add(new MenuSelection() { MenuName = "&Edit" });
    parent.list.Add(new MenuSelection() { MenuName = "&Save", ClickHandler = SaveClick4b });
    parent.list.Add(new MenuSelection() { MenuName = "&Delete", ClickHandler = DeleteClick4b });
    MenuSelection item = new MenuSelection();
    parent.list.Add(item);
    item.MenuName = "&Secret";

    // add a menu item that uses this anonymous delegate for its click event
    handler = new EventHandler(delegate(object sender, EventArgs ev)
    {
        MessageBox.Show("Knock knock.  Who's there?  Dunno...");
    });
    item.SubMenus.Add(new MenuSelection() { MenuName = "&Secret1", ClickHandler = handler });
    item.SubMenus.Add(new MenuSelection() { MenuName = "&Secret2", ClickHandler = delegate { MessageBox.Show("42"); } });


    parent.list.Add(new MenuSelection() { MenuName = "&Name", ClickHandler = NameClick4b });
    return parent;
}
private static void NameClick4b(object sender, EventArgs e)
{
    MenuItem mi = sender as MenuItem;
    MessageBox.Show("My name is " + mi.Text);
}
private static void SaveClick4b(object sender, EventArgs e)
{
    MessageBox.Show("I benn clikked!  Save me!");
}
private static void DeleteClick4b(object sender, EventArgs e)
{
    MessageBox.Show("I'm so gone...!");
}
private static void BuildMenus4b(MenuSelection item, MainMenu menuControl, MenuItem menuItem)
{
    MenuItem newItem = item.MakeMenuItem();
    if (menuItem == null)
    {
        menuControl.MenuItems.Add(newItem);
    }
    else
    {
        menuItem.MenuItems.Add(newItem);
    }
    foreach (MenuSelection thisItem in item.SubMenus)
    {
        BuildMenus4b(thisItem, menuControl, newItem);
    }
}
public class MenuParent
{
    public List<MenuSelection> list = new List<MenuSelection>();
}
public class MenuSelection
{
    public string MenuName { get; set; }
    public List<MenuSelection> SubMenus { get; set; }
    public EventHandler ClickHandler { get; set; }
    public MenuSelection()
    {
        ClickHandler = null;
        SubMenus = new List<MenuSelection>();
    }
    public MenuItem MakeMenuItem()
    {
        MenuItem item = new MenuItem(MenuName);
        if (ClickHandler != null)
            item.Click += new EventHandler(ClickHandler);
        return item;
    }
}
#endregion
 
Share this answer
 
Comments
frostcox 27-Jun-14 14:21pm    
Ah I see, what was confusing me was my application is a MVC web application but I can modify the logic to suit what I need, thank you so much for your help.
Maybe something like this would work for you...

C#
public class MenuInfo
{

    public short MenuId { get; set; }
    public string MenuName { get; set; }
    public string Url { get; set; }
    public short ParentmenuId { get; set; }
    public List<menuinfo> SubMenus {get; set;}
    public MenuItem MakeMenuItem()
    {
        MenuItem item = new MenuItem();
        // make your menu item here from properties
        return item;
    }
}


Here's your recursive method:

C#
private void BuildMenus(MenuInfo item, MainMenu menuControl, MenuItem menuItem)
{
    MenuItem newItem = item.MakeMenuItem();
    if (menuItem == null)
    {
        menuControl.MenuItems.Add(newItem);
    }
    else
    {
        menuItem.MenuItems.Add(newItem);
    }
    foreach (MenuInfo thisItem in item.SubMenus)
    {
        BuildMenus(thisItem, menuControl, newItem);
    }
}


And the initial call:

C#
public static void Example4()
{
    using (Form form = new Form())
    {
        form.Menu = CreateMainMenu();
        List<MenuInfo> list = CreateMenuInfos();
        foreach (MenuInfo info in list)
        {
            BuildMenus(info, form.Menu, null);
        }
        form.ShowDialog();
    }
}
 
Share this answer
 
v4
Comments
Francine DeGrood Taylor 26-Jun-14 18:27pm    
Oops, bug fix just now...The line that recursively calls BuildMenus in BuildMenus should have sent newItem, not menuItem.
CHill60 26-Jun-14 18:29pm    
I've added the "pre" tags around your code blocks ... makes your solution easier to read :-)
Francine DeGrood Taylor 27-Jun-14 12:41pm    
Thanks! I was having the darndest time getting this code formatted, for some reason.
frostcox 27-Jun-14 10:46am    
Thanks very much for your solution, only thing which is confusing me is this line where you instanciate MenuControl menu = new MenuControl();. MenuControl being what??. What I originally have is a List of Menuitems which is a list of all the menus in the database regardless of type parent/child, so at that point all the sub menus are null but the ParentMenuItemId is 0(parent) or ParentMenuItemId = MenuItemId for childern. How do I modify the above solution to cater for this scenario. Thanks again for your help.
Francine DeGrood Taylor 27-Jun-14 12:42pm    
MenuControl is the menu control for a form. You instantiate one and assign it to your form's .Menu property. I'll modify the code to show that.

What you need are a collection of objects (call them MenuItem) each representing a menu. Each of these objects has a list of MenuItems, each representing a menu selection. They have to be the same object type if you want to call them recursively. The "top" parent level object can also contain information about the menu as a whole (in the selection objects those properties would be unused).

If you want to give the menu and selection different classes (so you don't have unused properties) that would work as well. When you create your menu just pass the top level selection objects to the recursive method (I'll write you up a code example of what I'm talking about if you'd like)

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900