Results 1 to 15 of 15

Thread: Recursion - so simple [but my head fails]

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Aug 2003
    Location
    Edinburgh, UK
    Posts
    2,773

    Recursion - so simple [but my head fails]

    So I have this schema in the DB:

    ID (PK, int)
    ParentID (nullable int)
    MenuName

    I can select all records and thats great - populates an object for me with the above details (no SQL modification suggestions please)


    I want to be able to recursively go through the list of these items and be able to add sub menu items to the parent menu items. For example:

    ID ParentID MenuName
    1, NULL, "File"
    2, 1, "Open"
    3, 1, "Save"
    4, 1, "Save As",
    5, 1, "Export"
    6, 5, "To PDF"
    7, 5, "To Docx"
    8, 1, "Exit"


    As you can see, menuID's from 2 to 5 and 8 belong to "file". These are submenus
    Then we have menuID's 6 and 7 that belong to MenuID 5, which belong to MenuID 1

    Currently I have all the items in a List<MenuItem>

    This can change though where a 1 level submenu could become 2 levels...or x levels

    I want to be able to add sub menus to parents.

    makes sense?
    Last edited by Techno; Jan 10th, 2013 at 04:50 PM.

    MVP 2007-2010 any chance of a regain?
    Professional Software Developer and Infrastructure Engineer.

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Recursion - so simple [but my head fails]

    Are you saying that you want to be able to traverse that list and populate a MenuStrip with ToolStripMenuItems in the equivalent structure?

  3. #3
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Recursion - so simple [but my head fails]

    Assuming that the answer to my question is yes, use something like this:
    Code:
    private void PopulateMenu(IEnumerable<MenuItem> menuItems, ToolStripItemCollection parentMenu, int? parentID)
    {
        foreach (var menuItem in menuItems.Where(mi => mi.ParentID == parentID))
        {
            var childMenu = (ToolStripMenuItem) parentMenu.Add(menuItem.MenuName);
    
            // Recursive step
            PopulateMenu(menuItems, childMenu.DropDownItems, menuItem.ID);
        }
    }
    and set it off something like this:
    Code:
    PopulateMenu(menuItemList, menuStrip1.Items, null);

  4. #4

    Thread Starter
    PowerPoster
    Join Date
    Aug 2003
    Location
    Edinburgh, UK
    Posts
    2,773

    Re: Recursion - so simple [but my head fails]

    thank you. I will give this a shot.
    It isnt quite a MenuStrip or toolstrip collection as such but rather just a simple custom object (MenuItem I guess or another type of a collection of a custom object)

    MVP 2007-2010 any chance of a regain?
    Professional Software Developer and Infrastructure Engineer.

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Aug 2003
    Location
    Edinburgh, UK
    Posts
    2,773

    Re: Recursion - so simple [but my head fails]

    so let me clarify (still to test and alter your code):

    we have a collection of MenuItems. Each item represents a parent menu and also a submenu.
    Where the parentID is not null, that is how you identify that it is a submenu.

    I want to be able to "compile the list" so that the items are merged correctly i.e a parent has submenus and each of those submenus may have x submenus, and those could have x submenus etc...

    MVP 2007-2010 any chance of a regain?
    Professional Software Developer and Infrastructure Engineer.

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Recursion - so simple [but my head fails]

    I'm really not quite sure what you're trying to achieve then. Are you saying that a MenuItem has a property that is a collection of MenuItems and you want to populate those? You haven't really provided a clear explanation of exactly what you want to achieve, just a general description.

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Aug 2003
    Location
    Edinburgh, UK
    Posts
    2,773

    Re: Recursion - so simple [but my head fails]

    Sure, my apologies.

    What I want to achieve is to have a collection of menu items and each menu item can have x level deep submenus.
    The menu item is populated from the DB and mapped to the following object:

    Code:
    public class MenuItem
    {
       public int ID {get; set;}
       public int? ParentID {get; set; } // self referencing table, this points to "ID" if this MenuItem is a submenu of a parent
       public string MenuName { get; set; }
    }
    So when I obtain all records from the DB, each item is placed in a List<MenuItem> which includes parent and submenu items.

    I then want to finally be able to correctly create the structure where for each menu item, it will find its child menu items and for each of those child items...finds its child items and so on....
    So yes, the MenuItem could potentially have its own collection of MenuItems as submenus

    does this help?

    MVP 2007-2010 any chance of a regain?
    Professional Software Developer and Infrastructure Engineer.

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Recursion - so simple [but my head fails]

    Surely your MenuItem class would need a Children collection property for that to be feasible, in which case you would populate it in the first place, right from the database.

  9. #9

    Thread Starter
    PowerPoster
    Join Date
    Aug 2003
    Location
    Edinburgh, UK
    Posts
    2,773

    Re: Recursion - so simple [but my head fails]

    not sure I follow.
    there is no way the DB end can do what I am wanting to do (And I cant touch the DB).

    Sure, the MenuItems class can add a Collections property - done. But now what? how can I populate that and for each of those populate the child nodes etc.... ?

    The DB just has the one table as mentioned previously which has the list of all the parent menus, sub menus and other children menus. i now need to make it into a representable way to show the relationship

    MVP 2007-2010 any chance of a regain?
    Professional Software Developer and Infrastructure Engineer.

  10. #10
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Recursion - so simple [but my head fails]

    Show us the code you have at the moment for reading the data from the database into the List. That code will need to be modified to read the data into a tree structure. You will still use the List to store all the top-level items but the other items will now be stored in the Children (or whatever name you've used) collection of their parent.

  11. #11

    Thread Starter
    PowerPoster
    Join Date
    Aug 2003
    Location
    Edinburgh, UK
    Posts
    2,773

    Re: Recursion - so simple [but my head fails]

    Right

    ok, so here is the code for the DB SQL Statement:

    Code:
    SELECT m.MenuID, m.MenuName, m.ParentID, m.URL 
    FROM Menus m
    INNER JOIN UserMenus um ON
    um.MenuID = m.MenuID
    INNER JOIN User u ON 
    u.UserID = m.UserID
    
    WHERE u.UserID = @userID
    thats all that there is. this gives back a typical resultset like the following:

    1 File NULL NULL
    2 Software Security 1 ~/SoftwareSecurity/SoftwareSecurity_Qry.aspx
    47 Employee Directory 1 ~/Employee/EmployeeDirectory.aspx
    53 HandBook 1 NULL
    50 News 1 ~/Calendar/News_List.aspx
    48 Calendar 1 NULL
    3 Change Password 1 NULL
    59 Change Account 1 NULL
    4 Exit 1 NULL
    5 Asset NULL NULL
    6 Asset Inquiry 5 NULL
    7 Check In/Out/Xfer 5 NULL
    8 Control File 5 NULL
    10 Shipper List 5 NULL
    12 DocSS 5 NULL
    58 Upload Data 5 NULL
    24 Purchase Order NULL NULL
    26 Vendor 24 NULL
    27 Reporting NULL NULL
    35 Maintenance NULL NULL
    36 Employee 35 NULL
    37 Employee Profile 36 NULL
    38 Employee Titles 36 NULL
    40 Equipment Due Cal/Return Settings 35 NULL
    41 Equipment Location List 35 NULL
    42 Log Issues 35 NULL
    45 Help NULL NULL
    46 About Tam Online 45 NULL
    67 Handbook 1 ~/Docs/Handbook.pdf
    68 Holidays/Pay Dates 1 ~/Docs/HolidayCalendar_2011.pdf
    Makes sense?

    So right now, the code reads all these records into an object called MenuItem. Each MenuItem is in a List<MenuItem>

    I want to go a step further and correctly display/represent the children, and their children, and their children etc.... in the object(s) correctly.

    MVP 2007-2010 any chance of a regain?
    Professional Software Developer and Infrastructure Engineer.

  12. #12
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Recursion - so simple [but my head fails]

    Quote Originally Posted by Techno View Post
    So right now, the code reads all these records into an object called MenuItem.
    That would be the code that I asked you to provide that you haven't, right?

  13. #13

    Thread Starter
    PowerPoster
    Join Date
    Aug 2003
    Location
    Edinburgh, UK
    Posts
    2,773

    Re: Recursion - so simple [but my head fails]

    huh? It's there. I posted it

    MVP 2007-2010 any chance of a regain?
    Professional Software Developer and Infrastructure Engineer.

  14. #14
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Recursion - so simple [but my head fails]

    If you're talking about the fact that your MenuItem class has a ParentID property then you are mistaken. That is absolutely not the same thing. Think about the innumerable examples in the .NET Framework. If a DataSet contains DataTables, does each DataTable have a reference to the DataSet? No, the DataSet has a Tables collection and it contains a reference to each DataTable. Do you see the difference?

  15. #15

    Thread Starter
    PowerPoster
    Join Date
    Aug 2003
    Location
    Edinburgh, UK
    Posts
    2,773

    Re: Recursion - so simple [but my head fails]

    yes I do. but what im saying is that this is how the DB TABLE structure is, and a DTO has been made from it.
    The table structure is self referencing. ParentID is linked to MenuID
    a Menu can have children. each child could have children, each of those could have children etc....
    so I need to take that raw data and populate it "correctly", if you like, in the class to represent this relationship/hierarchy

    MVP 2007-2010 any chance of a regain?
    Professional Software Developer and Infrastructure Engineer.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width