Programmatic Menus: Optimize Your Menus in Code-behind
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:
Front | Behind 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