0

I have a contextMenuStrip that generated dynamical form data in a database. The data in the database has a group column and i want to use it to create Sub Menu's dynamically for the application. My problem is that it creates duplicate sub menu items and i want it grouped.

this is my List and Constructor.

List<Tuple<WebLinks>> WebLinksList = new List<Tuple<WebLinks>>();

class WebLinks
{
    public string Name { get; set; }
    public string Link { get; set; }
    public string Group { get; set; }
}

So far this is the working code to build the context menu but I need this to change to the Group view and not just show the Name.

private void CreateMenu()
{

    foreach (Tuple<WebLinks> wl in WebLinksList)
    {
        contextMenuStripMain.Items.Add(wl.Item1.Name);
    }
    contextMenuStripMain.Items.Add("-");
    contextMenuStripMain.Items.Add("Settings");
    contextMenuStripMain.Items.Add("Exit");
}

The above works fine but nothing is grouped, so i need to work in the "wl.Item1.Group" in somewhere but google was no help in my situation.

I tired This Stack Overflow and it gave me the duplicate Groups where i tried to filter it but with no luck. Hope I made sense.

Community
  • 1
  • 1
Psystec
  • 1
  • 1
  • 4

2 Answers2

1

You can use LINQ to group your objects:

private void CreateMenu()
{
    foreach (var group in WebLinksList.GroupBy(wl => wl.Item1.Group))
    {
        var groupItem = new ToolStripMenuItem(group.Key);
        contextMenuStripMain.Items.Add(groupItem);
        groupItem.DropDownItems.AddRange(group.Select(w => new ToolStripMenuItem(w.Item1.Name)).ToArray<ToolStripItem>());
    }

    contextMenuStripMain.Items.Add("-");
    contextMenuStripMain.Items.Add("Settings");
    contextMenuStripMain.Items.Add("Exit");
}

So for each distinct Group a single menu item will be added. To this item the sub items of this group are added by Name.

[EDIT] I now create groupItem as ToolStripMenuItem and add the sub items to the DropDownItems property.

René Vogt
  • 43,056
  • 14
  • 77
  • 99
  • Thank you very much, i see what you are doing here but for some reason "groupItem.Items.AddRange" is giving errors, ToolStripItem does not contain the definition for 'Items' and no extention method 'Items'. – Psystec Jan 19 '16 at 11:40
  • @Psystec Yes there was a mistake. `Items.Add` returns an abstract `ToolStripItem` which doesn't know about sub-items. The `ToolStripMenuItem` has the sub-items, but named `DropDownItems` instead of `Items`. Updated my answer. – René Vogt Jan 19 '16 at 11:52
  • Thanks man, you are the best. it is working like a charm, i see that you need a click event for sub menus. – Psystec Jan 19 '16 at 14:25
0

Thanks René Vogt. I fixed if before I read your answer but desided to go with yours anyway.

This was your fix, i just added a click event for the sub menu's.

        foreach (var group in WebLinksList.GroupBy(wl => wl.Level))
        {
            var groupItem = new ToolStripMenuItem(group.Key);
            contextMenuStripMain.Items.Add(groupItem);
            groupItem.DropDownItemClicked += Tm_DropDownItemClicked;
            groupItem.DropDownItems.AddRange(group.Select(w => new ToolStripMenuItem(w.Name)).ToArray<ToolStripItem>());
        }

This was my Fix but it is the same.

        foreach (var group in WebLinksList.GroupBy(wl => wl.Level))
        {
            ToolStripMenuItem tm = new ToolStripMenuItem();
            tm.Text = group.Key;
            tm.DropDownItemClicked += Tm_DropDownItemClicked;
            tm.DropDownItems.AddRange(group.Select(w => new ToolStripMenuItem(w.Name)).ToArray<ToolStripItem>());
            contextMenuStripMain.Items.Add(tm);
        }

Anyway, I would not have done it without you. Thanks

Psystec
  • 1
  • 1
  • 4
  • I forgot to say that i removed the Tuple in the list as it was not needed because i have a class that will handle that. – Psystec Jan 19 '16 at 13:50