views:

710

answers:

2

I am trying to construct a TreeView from a Menu. My Code is like this:

public class MenuExtractionUtility
    {
        public TreeView MenuTraverse(MainMenu mainMenu)
        {
            TreeView treeView = new TreeView();

            TreeNode mainNode = new TreeNode();

            foreach (MenuItem mi in mainMenu.MenuItems)
            {
                System.Diagnostics.Debug.WriteLine(mi.Text);

                mainNode.Text = mi.Text;

                TreeNode tn = MenuItemTraverse(mi);

                mainNode.Nodes.Add(tn);
            }

            treeView.Nodes.Add(mainNode);

            return treeView;
        }

        private TreeNode MenuItemTraverse(MenuItem menuItem)
        {
            TreeNode treeNode = new TreeNode();

            foreach(MenuItem mi in menuItem.MenuItems)
            {
                System.Diagnostics.Debug.WriteLine(mi.Text);

                treeNode.Text = mi.Text;

                TreeNode tr = MenuItemTraverse(mi);

                if (tr!=null && tr.Text != "")
                {
                    treeNode.Nodes.Add(tr);
                }
            }

            return treeNode;
        }
    }

But this is not working.

What can be the problem?

+1  A: 

I think there are two problems in the methods. Let's start with the MenuItemTraverse method. You get a MenuItem as input. You declare a TreeNode variable, and assign a new TreeNode instance to it. Then you loop over the menu item's sub items. For each iteration you assign the text from the sub item to the TreeNode (I would assume that you would want the text of the incoming menu item on this TreeNode). To get the intended behaviour you should remove this line from the loop:

treeNode.Text = mi.Text;

...and add this line before the loop:

treeNode.Text = menuItem.Text;

It looks like you have the exact same problem in the MenuTraverse method, so do the same change there. I think that would solve it for you (didn't test the code yet; might have missed something).

Update

I gave it a bit of though, since I felt that the code could probably be simplified a bit, and this is what I came up with. Instead of having two different methods for MainMenu and MenuItem input, this one encapsulates the process into one single method. Also, it takes a TreeNodeCollection, which means that you can have the method inject the menu structure into an already existing (and populated) TreeView control, at any level in the tree.

public class MenuExtractionUtility
{
    public static void MenuItemTraverse(TreeNodeCollection parentCollection, Menu.MenuItemCollection menuItems)
    {
        foreach (MenuItem mi in menuItems)
        {
            System.Diagnostics.Debug.WriteLine(mi.Text);
            TreeNode menuItemNode = parentCollection.Add(mi.Text);
            if (mi.MenuItems.Count > 0)
            {
                MenuItemTraverse(menuItemNode.Nodes, mi.MenuItems);
            }
        }
    }
}

Usage example:

treeView1.Nodes.Clear();
MenuExtractionUtility.MenuItemTraverse(treeView1.Nodes, mainMenu1.MenuItems);

This code was just quickly put together, so you may want to "stabilize" it a bit by adding null checks and similar.

Fredrik Mörk
Sorry I was busy testing your code. Excellent job @Fredrik!Meanwhile I have come up with my own corrections buddy!
A: 

here it is...

public class MenuExtractionUtility
    {
        public void MenuTraverse(MainMenu mainMenu, TreeView treeView)
        {
            TreeNode ultimateMainNode = new TreeNode();
            ultimateMainNode.Text = "Root";

            TreeNode mainNode = null;

            foreach (MenuItem mi in mainMenu.MenuItems)
            {
                if (mi != null && mi.Text != "")
                {
                    mainNode = null;

                    if (mi.MenuItems.Count <= 0)
                    {
                        mainNode = new TreeNode();
                        mainNode.Text = mi.Text;
                    }
                    else if (mi.MenuItems.Count > 0)
                    {
                        mainNode = MenuItemTraverse(mi);
                    }

                    ultimateMainNode.Nodes.Add(mainNode);
                }
            }

            treeView.Nodes.Add(ultimateMainNode);
        }

        private TreeNode MenuItemTraverse(MenuItem menuItem)
        {
            TreeNode treeNode = new TreeNode();
            System.Diagnostics.Debug.Write(menuItem.Text+",");
            treeNode.Text = menuItem.Text;

            foreach (MenuItem mi in menuItem.MenuItems)
            {
                if (mi != null && mi.Text != "")
                {
                    TreeNode tr = MenuItemTraverse(mi);

                    if (tr != null && tr.Text != "")
                    {
                        treeNode.Nodes.Add(tr);
                    }
                }
            }

            return treeNode;
        }
JMSA