Shining Star Services LLC

Programmatic Menus: Optimize Your Menus in Code-behind

By Nannette Thacker

In this article, I want to show how you can setup your menus in code-behind and avoid redundancy. I recently inherited a web application with the menu system setup in the code-in-front. Each menu shared identical values, other than the visibility. Notice that numerous properties are defined more than once, above and below the MenuItems. What's as bad is that this entire block of code was repeated for 6 additional menus.

Example of Redundant, Bloated Menu Setup

<asp:Menu StaticMenuItemStyle-Font-Bold="true" Visible="true" 
    StaticMenuItemStyle-ForeColor="white"
    StaticMenuStyle-HorizontalPadding="4" StaticMenuItemStyle-Font-Names="verdana"
    DynamicMenuItemStyle-Font-Names="verdana" DynamicMenuItemStyle-Font-Size="Smaller"
    StaticMenuItemStyle-Font-Size="Small" BorderColor="darkblue" BorderWidth="1"
    DynamicMenuItemStyle-BorderWidth="2" DynamicMenuItemStyle-BorderColor="#CCCCCC"
    DynamicHoverStyle-BackColor="wheat" DynamicHoverStyle-ForeColor="black" 
    DynamicHoverStyle-Font-Bold="true"
    DynamicMenuItemStyle-VerticalPadding="4" DynamicMenuItemStyle-HorizontalPadding="4"
    DynamicSelectedStyle-BorderStyle="None" ID="Menu1" runat="server" 
    Font-Underline="False" Width="90px">
    <Items>
        <asp:MenuItem>...</asp:MenuItem>
    </Items>
    <StaticMenuItemStyle Font-Underline="False" Font-Bold="True" Font-Names="verdana"
        Font-Size="Small" ForeColor="White" />
    <DynamicMenuStyle BackColor="#F2F8FF" BorderColor="LightSkyBlue" 
    BorderStyle="Solid" BorderWidth="1px" />
    <DynamicMenuItemStyle Font-Underline="False" BorderColor="#CCCCCC" BorderWidth="2px"
        Font-Names="verdana" Font-Size="Smaller" HorizontalPadding="4px" 
        VerticalPadding="4px" />
    <StaticMenuStyle HorizontalPadding="4px" />
    <DynamicHoverStyle BackColor="Wheat" Font-Bold="True" ForeColor="Black" />
    <DynamicSelectedStyle BorderStyle="None" />
</asp:Menu>
If a property needs changed, the programmer must make certain that the change is made in all six instances of this block of code, for each menu, as well as realizing that certain properties are defined twice. This type of coding can introduce problems after updates and edits.

To optimize this menu, let's move this to the code-behind so that if a change is needed, it is only needed in one line of code. In our code-in-front, we'll simply setup the menus like so:

Streamlined Menu

<asp:Menu ID="Menu1" runat="server">
    <Items>
        <asp:MenuItem>...</asp:MenuItem>
    </Items>
</asp:Menu>
<asp:Menu ID="Menu2" runat="server">
    <Items>
        <asp:MenuItem>...</asp:MenuItem>
    </Items>
</asp:Menu>
...and so forth

In our codebehind, we'll setup each menu in our Page_Load and define one function that will set the properties for each menu:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

                MenuSetup(Menu1, True)
                MenuSetup(Menu2, True)
                MenuSetup(Menu3, True)
                MenuSetup(Menu4, False)
                MenuSetup(Menu5, False)
                MenuSetup(Menu6, False)
        
End Sub
Remember I said that the only difference in these menus was the visibility? So in our MenuSetup function we'll pass in the menu ID, as well as whether the menu should be visible or not. I've altered some of the values from what you see in the original code-in-front, but you get the idea. Be sure to import System.Drawing for the colors.

Protected Sub MenuSetup(ByVal myMenu As Menu, ByVal visibility As Boolean)

        myMenu.Visible = visibility
        myMenu.BorderColor = Drawing.Color.Black
        myMenu.BorderWidth = Unit.Pixel(1)
        myMenu.Font.Underline = False
        myMenu.Width = Unit.Pixel(90)
        
        myMenu.StaticMenuStyle.HorizontalPadding = Unit.Pixel(4)

        myMenu.StaticMenuItemStyle.Font.Bold = True
        myMenu.StaticMenuItemStyle.Font.Name = "Verdana"
        myMenu.StaticMenuItemStyle.Font.Size = "10"
        myMenu.StaticMenuItemStyle.Font.Underline = False
        myMenu.StaticMenuItemStyle.ForeColor = Color.White
        
        myMenu.DynamicMenuStyle.BorderWidth = Unit.Pixel(1)

        myMenu.DynamicMenuItemStyle.Font.Bold = True
        myMenu.DynamicMenuItemStyle.Font.Name = "Verdana"
        myMenu.DynamicMenuItemStyle.Font.Size = "8"
        myMenu.DynamicMenuItemStyle.BorderWidth = Unit.Pixel(1)
        myMenu.DynamicMenuItemStyle.BorderColor = ColorTranslator.FromHtml("#CCCCCC")
        myMenu.DynamicMenuItemStyle.BorderStyle = BorderStyle.None
        myMenu.DynamicMenuItemStyle.VerticalPadding = Unit.Pixel(4)
        myMenu.DynamicMenuItemStyle.HorizontalPadding = Unit.Pixel(4)
        myMenu.DynamicMenuItemStyle.ForeColor = Color.Black
        myMenu.DynamicMenuItemStyle.BackColor = ColorTranslator.FromHtml("#F0F2F4")

        myMenu.DynamicHoverStyle.BackColor = ColorTranslator.FromHtml("#CCCCCC") 
        myMenu.DynamicHoverStyle.ForeColor = ColorTranslator.FromHtml("#00008B")  

        myMenu.DynamicSelectedStyle.ForeColor = ColorTranslator.FromHtml("#00008B")

    End Sub
Notice some of the differences when defining properties in the code-behind:

FrontBehind
Imports System.Drawing ' for Colors
Width="90px"myMenu.Width = Unit.Pixel(90)
StaticMenuItemStyle-Font-Bold="true"myMenu.StaticMenuItemStyle.Font.Bold = True
Visible="true"myMenu.Visible = visibility
StaticMenuStyle-HorizontalPadding="4"myMenu.StaticMenuStyle.HorizontalPadding = Unit.Pixel(4)
StaticMenuItemStyle-Font-Names="verdana"myMenu.StaticMenuItemStyle.Font.Name = "Verdana"
(singular .Name for one)
StaticMenuItemStyle-Font-Size="Small"myMenu.StaticMenuItemStyle.Font.Size = "10"
DynamicMenuItemStyle-BorderWidth="2"myMenu.DynamicMenuItemStyle.BorderWidth = Unit.Pixel(2)
DynamicMenuItemStyle-BorderColor="#CCCCCC"myMenu.DynamicMenuItemStyle.BorderColor = ColorTranslator.FromHtml("#CCCCCC")
DynamicHoverStyle-BackColor="wheat"myMenu.DynamicMenuItemStyle.BackColor = Color.Wheat
DynamicHoverStyle-Font-Bold="true"myMenu.DynamicHoverStyle.Font.Bold = True
DynamicSelectedStyle-BorderStyle="None"myMenu.DynamicSelectedStyle.BorderStyle = BorderStyle.None

May your dreams be in ASP.NET!

Nannette Thacker
© Copyright 1997-2017 Shining Star Services LLC, Nannette Thacker. All Rights Reserved.