MenuItemExample.png

For the Menu, I abstracted away the typical BeginComposite...EndComposite, hiding these inside a custom BeginMenuComposite...EndMenuComposite. This helps make the code even more concise.

Notice that for simplicity, regular Menus are used for the sub-menus as well. These sub-menus are displayed OnClick of a MenuItem. The sub-menus are wrapped in a Border parent and added as children to a Canvas parent (which is a child of MainWindow.) Canvas allows support of Z-Index.

WPF Composites is all about Parent-Child relationships and nested parent-children.

A typical hierarchy might be:

Menu - MenuItem
- MenuItem
- MenuItem >>>OnClick, add Border to base Canvas at Z-Index: 99 >>>
Canvas - Border - Menu - MenuItem
- MenuItem
- MenuItem
This approach may be reminiscent of old-school DHTML menus on the web which would hide or show DIV tags on click or mouseover of a menu-item. In WPF, perhaps the Border may be the new DIV tag?

In the demo app, in MenuBuilder.cs, I include at the bottom a commented-out section of code that shows an example of using the regular Aero theme color & styling with regular sub-menus (IsSubmenuOpen). However, my assumption is that most developers prefer to style the menu to suit their own taste with their own custom colors, etc. as shown in the code example below and the screenshot above which leverage the more DHTML-like approach:

//TOP-LEVEL MENU BAR
mnu = FasterWPF.Factory
            .BeginMenuSettings(double.NaN, 20D, ContainerType.HorizontalPanel, Brushes.WhiteSmoke)
            .SetItemBorderSettings<Menu>(110D, 20D, Brushes.Silver, new Thickness(2))
            .EndMenuSettings();

 . . . . . . . . 

public static class MenuBuilder
    {
        public static void BuildMenu(Menu mnu, Canvas cnvs, string cnvsguid2, string cnvsguid3, string submnuguid0, string submnuguid1)
        {
            //MENU ITEM 1
            MenuItem m1 = FasterWPF.Factory
            .BeginMenuComposite("_File", mnu, Brushes.WhiteSmoke, Brushes.WhiteSmoke, Brushes.Black, Brushes.Black, "Verdana", 12, FontWeights.Bold, FontStyles.Normal, Brushes.WhiteSmoke)
            .SetMouseOverBorderColor(Brushes.Gray)
            .AddMenuItem((o, ev) => { MessageBox.Show("Clicked File!"); })
            .EndMenuComposite();

            //SUB-MENU 1
            //Step 1: create a Border to hold the sub-menu and set it to hide itself on mouse-out
            Border subMenuBorder = new Border();
            subMenuBorder.Initialize(230D, 100D, ContainerType.HorizontalPanel, Brushes.Gray, new Thickness(1), Brushes.WhiteSmoke);
            subMenuBorder.BeginSettings<Border>().SetItemBorderSettings<Border>(230D, 100D, Brushes.LightGray, new Thickness(1)).EndSettings<Border>();
            subMenuBorder.SubscribeEventOnParent<Border>("MouseLeave",
                new MouseEventHandler((o, mse) =>
                {
                    //a: On mouse out, hide sub-menu
                    MenuItemExt.HideSubMenu(cnvs, cnvsguid2);
                }));

            //Step 2: create the submenu and set its orientation to vertical
            Menu subMenu1 = FasterWPF.Factory
           .BeginMenuSettings(230D, 100D, ContainerType.HorizontalPanel, Brushes.WhiteSmoke)
                //    .SetItemBorderSettings<Menu>(173D, 20D, Brushes.Silver, new Thickness(1))
           .EndMenuSettings();
            MenuItemExt.SetMenuOrientationToVertical(subMenu1);

            //Step 3: add the individual menuitems to the submenu
            MenuItem subMenuItem1 = FasterWPF.Factory
             .BeginMenuComposite(225D, 20D, "_Choice #1", subMenu1, Brushes.LightSkyBlue, Brushes.WhiteSmoke, Brushes.Black, Brushes.Black, "Verdana", 10, FontWeights.SemiBold, FontStyles.Normal, Brushes.WhiteSmoke)
             .SetMouseOverBorderColor(Brushes.Gray)
             .AddMenuItem((o, ev) => { MessageBox.Show("Clicked Choice #1!"); })
             .EndMenuComposite();

            MenuItem subMenuItem2 = FasterWPF.Factory
             .BeginMenuComposite(225D, 20D, "_This is a longer choice", subMenu1, Brushes.LightSkyBlue, Brushes.WhiteSmoke, Brushes.Black, Brushes.Black, "Verdana", 10, FontWeights.SemiBold, FontStyles.Normal, Brushes.WhiteSmoke)
             .SetMouseOverBorderColor(Brushes.Gray)
             .AddMenuItem((o, ev) => { MessageBox.Show("Clicked 'This is a longer choice.'"); })
             .EndMenuComposite();

            MenuItem subMenuItem3 = FasterWPF.Factory
             .BeginMenuComposite(225D, 20D, "_Edit Vacation Profile", subMenu1, Brushes.LightSkyBlue, Brushes.WhiteSmoke, Brushes.Black, Brushes.Black, "Verdana", 10, FontWeights.SemiBold, FontStyles.Normal, Brushes.WhiteSmoke)
             .SetMouseOverBorderColor(Brushes.Gray)
             .AddMenuItem((o, ev) => { MessageBox.Show("Clicked 'Edit Vacation Profile.'"); })
             .EndMenuComposite();

            //Step 4: add the sub-menu to the Border
            subMenuBorder.BeginComposite(submnuguid0)
              .AddExisting<Menu, Border>(0, 0, subMenu1)
              .EndComposite<Border, BorderArgs>(null);

            //Step 5: create another main level menu item and add the Border to it via wiring On Click event

            //MENU ITEM 2 with Sub-Menu
            MenuItem m2 = FasterWPF.Factory
            .BeginMenuComposite("_Edit", mnu, Brushes.WhiteSmoke, Brushes.WhiteSmoke, Brushes.Black, Brushes.Black, "Verdana", 12, FontWeights.Bold, FontStyles.Normal, Brushes.WhiteSmoke)
            .SetMouseOverBorderColor(Brushes.Gray)
            .AddMenuItem((o, ev) =>
            {

                //b: On click, display sub-menu
                MenuItemExt.DisplaySubMenu(cnvs, cnvsguid2, subMenuBorder, 120D, 21D, 500);
                MenuItemExt.HideSubMenu(cnvs, cnvsguid3);
            })
            .EndMenuComposite();

            //SUB-MENU 2
            //Step 1: create a Border to hold the sub-menu and set it to hide itself on mouse-out
            Border subMenuBorder2 = new Border();
            subMenuBorder2.Initialize(230D, 27D, ContainerType.HorizontalPanel, Brushes.Gray, new Thickness(1), Brushes.WhiteSmoke);
            subMenuBorder2.BeginSettings<Border>().SetItemBorderSettings<Border>(230D, 27D, Brushes.LightGray, new Thickness(1)).EndSettings<Border>();
            subMenuBorder2.SubscribeEventOnParent<Border>("MouseLeave",
                new MouseEventHandler((o, mse) =>
                {
                    //a: On mouse out, hide sub-menu
                    MenuItemExt.HideSubMenu(cnvs, cnvsguid3);
                }));

            //Step 2: create the submenu and set its orientation to vertical
            Menu subMenu2 = FasterWPF.Factory
           .BeginMenuSettings(230D, 27D, ContainerType.HorizontalPanel, Brushes.WhiteSmoke)
           .EndMenuSettings();
            MenuItemExt.SetMenuOrientationToVertical(subMenu2);

            //Step 3: add the individual menuitems to the submenu
            MenuItem subMenu2Item1 = FasterWPF.Factory
             .BeginMenuComposite(225D, 20D, "_View Vacation Photos", subMenu2, Brushes.LightSkyBlue, Brushes.WhiteSmoke, Brushes.Black, Brushes.Black, "Verdana", 10, FontWeights.SemiBold, FontStyles.Normal, Brushes.WhiteSmoke)
             .SetMouseOverBorderColor(Brushes.Gray)
             .AddMenuItem((o, ev) => { MessageBox.Show("Clicked 'View Vacation Photos'"); })
             .EndMenuComposite();

            //Step 4: add the sub-menu to the Border
            subMenuBorder2.BeginComposite(submnuguid1)
              .AddExisting<Menu, Border>(0, 0, subMenu2)
              .EndComposite<Border, BorderArgs>(null);

            //Step 5: create another main level menu item and add the Border to it via wiring On Click event

            //MENU ITEM 3
            MenuItem m3 = FasterWPF.Factory
            .BeginMenuComposite("_View", mnu, Brushes.WhiteSmoke, Brushes.WhiteSmoke, Brushes.Black, Brushes.Black, "Verdana", 12, FontWeights.Bold, FontStyles.Normal, Brushes.WhiteSmoke)
            .SetMouseOverBorderColor(Brushes.Gray)
            .AddMenuItem((o, ev) =>
            {
                //b: On click, display sub-menu
                MenuItemExt.DisplaySubMenu(cnvs, cnvsguid3, subMenuBorder2, 235D, 21D, 500);
                MenuItemExt.HideSubMenu(cnvs, cnvsguid2);
            })
            .EndMenuComposite();
        }
    }






Last edited Dec 27, 2012 at 7:20 PM by stagathome0069, version 16

Comments

No comments yet.