What the code does is displays a row of buttons and when you click on a button it changes the session so you can see if it's active or not.
Also, this is a link to what the side panel looks like when you click the "programming" button.
There must be a better way to display this code. Does anyone have any ideas?
<td class="mainMenuPanelTD">
<%if ((string)HttpContext.Current.Session["whichTopMenu"] == "programming")
{%>
<asp:Button class='mainMenuPanelButtonSelected boxShadowClass'
onclientclick="doFade()"
onclick='topMenuClick' id='programming' type='button' runat='server'
text='<%#(string)HttpContext.Current.Session["programmingButtonValue"]%>'/>
<%}
else
{%>
<asp:Button class='mainMenuPanelButton boxShadowClass'
onclientclick="doFade()"
onclick='topMenuClick' id='programming1' type='button' runat='server'
text='<%#(string)HttpContext.Current.Session["programmingButtonValue"]%>'/>
<%}%>
</td>
<td class="mainMenuPanelTD">
<%if ((string)HttpContext.Current.Session["whichTopMenu"] == "management")
{%>
<asp:Button class='mainMenuPanelButtonSelected boxShadowClass'
onclientclick="doFade()"
onclick='topMenuClick' id='management' type='button'
runat='server' text='<%#(string)HttpContext.Current.Session["managementButtonValue"]%>'/>
<%}
else
{%>
<asp:Button class='mainMenuPanelButton boxShadowClass'
onclientclick="doFade()"
onclick='topMenuClick' id='management1' type='button'
runat='server' text='<%#(string)HttpContext.Current.Session["managementButtonValue"]%>'/>
<%}%>
</td>
<td class="mainMenuPanelTD">
<%if ((string)HttpContext.Current.Session["whichTopMenu"] == "service")
{%>
<asp:Button class='mainMenuPanelButtonSelected boxShadowClass disabled-button'
onclientclick="doFade()"
onclick='topMenuClick' id='service' type='button'
runat='server' text='<%#(string)HttpContext.Current.Session["serviceButtonValue"]%>'/>
<%}
else
{%>
<asp:Button class='mainMenuPanelButton boxShadowClass disabled-button'
onclientclick="doFade()"
onclick='topMenuClick' id='service1' type='button'
runat='server' text='<%#(string)HttpContext.Current.Session["serviceButtonValue"]%>'/>
<%}%>
</td>
<td class="mainMenuPanelTD">
<%if ((string)HttpContext.Current.Session["whichTopMenu"] == "system")
{%>
<asp:Button class='mainMenuPanelButtonSelected boxShadowClass'
onclientclick="doFade()"
onclick='topMenuClick' id='system' type='button'
runat='server' text='<%#(string)HttpContext.Current.Session["systemButtonValue"]%>'/>
<%}
else
{%>
<asp:Button class='mainMenuPanelButton boxShadowClass'
onclientclick="doFade()"
onclick='topMenuClick' id='system1' type='button'
runat='server' text='<%#(string)HttpContext.Current.Session["systemButtonValue"]%>'/>
<%}%>
</td>
<td class="mainMenuPanelTD">
<%if ((string)HttpContext.Current.Session["whichTopMenu"] == "reports")
{%>
<asp:Button class='mainMenuPanelButtonSelected boxShadowClass disabled-button'
onclientclick="doFade()"
onclick='topMenuClick' id='reports' type='button'
runat='server' text='<%#(string)HttpContext.Current.Session["reportsButtonValue"]%>'/>
<%}
else
{%>
<asp:Button class='mainMenuPanelButton boxShadowClass disabled-button'
onclientclick="doFade()"
onclick='topMenuClick' id='reports1' type='button'
runat='server' text='<%#(string)HttpContext.Current.Session["reportsButtonValue"]%>'/>
<%}%>
</td>
<td class="mainMenuPanelTD">
<%if ((string)HttpContext.Current.Session["whichTopMenu"] == "scheduling")
{%>
<asp:Button class='mainMenuPanelButtonSelected boxShadowClass'
onclientclick="doFade()"
onclick='topMenuClick' id='scheduling' type='button'
runat='server' text='<%#(string)HttpContext.Current.Session["schedulingButtonValue"]%>'/>
<%}
else
{%>
<asp:Button class='mainMenuPanelButton boxShadowClass'
onclientclick="doFade()"
onclick='topMenuClick' id='scheduling1' type='button'
runat='server' text='<%#(string)HttpContext.Current.Session["schedulingButtonValue"]%>'/>
<%}%>
</td>
<td class="mainMenuPanelTD">
<%if ((string)HttpContext.Current.Session["whichTopMenu"] == "wvnusers")
{%>
<asp:Button class='mainMenuPanelButtonSelected boxShadowClass'
onclientclick="doFade()"
onclick='topMenuClick' id='wvnusers' type='button'
runat='server' text='<%#(string)HttpContext.Current.Session["wvnusersButtonValue"]%>'/>
<%}
else
{%>
<asp:Button class='mainMenuPanelButton boxShadowClass'
onclientclick="doFade()"
onclick='topMenuClick' id='wvnusers1' type='button'
runat='server' text='<%#(string)HttpContext.Current.Session["wvnusersButtonValue"]%>'/>
<%}%>
</td>
<td class="mainMenuPanelTD">
<asp:Button class='mainMenuPanelButton boxShadowClass'
onclientclick="doFade()"
onclick='logoutClick' id='logoutButton' type='button' runat='server'
text='<%#(string)HttpContext.Current.Session["logoutButtonValue"]%>'/>
</td>
1 Answer 1
This can be shortened up quite a bit. First, you have presentation logic intertwined in your ASP code, which is the main cause for the code repetition. Shortening this code and DRY-ing it up involves two main pieces:
- create a user control to encompass this menu, and only this menu
- Move all presentation logic into the C# code-behind file
Creating the User Control
First, create a brand new user control and name it something like "MenuUserControl"
<table>
<tr>
<td class="mainMenuPanelTD">
<asp:Button id='programming1' runat='server'
onclientclick="doFade()"
onclick='topMenuClick' type='button'/>
</td>
<td class="mainMenuPanelTD">
<asp:Button id='management1' runat='server'
onclientclick="doFade()"
onclick='topMenuClick' type='button'/>
</td>
<!-- more menu items ... -->
Notice that the CssClass
and the button Text
is not in the Design file. Moving this into C# not only makes the Design code cleaner, but the resulting C# could will still look pretty clean, and it allows you to leverage Visual Studio's refactoring tools in the future should anything change.
The Code-Behind file:
public partial class MenuUserControl : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
SetButtonText();
}
private void SetButtonText()
{
programming1.Text = (string)Session["programmingButtonValue"];
management1.Text = (string)Session["managementButtonValue"];
// continue setting button text...
}
public void SetActiveButton(string activeButtonId)
{
SetButtonState(programming1, activeButtonId);
SetButtonState(management1, activeButtonId);
// continue setting button state..
}
private void SetButtonState(Button button, string activeButtonId)
{
button.CssClass = button.ID == activeButtonId
? "mainMenuPanelButtonSelected boxShadowClass"
: "mainMenuPanelButton boxShadowClass";
}
}
During the initial GET request to your web application, set the button text using the Session
, as described in the SetButtonText
private method.
Next, the SetActiveButton
method is exposed publically so a parent user control can give the menu control the name of the active button. The logic of "setting the active button" is encapsulated in the SetButtonState
class, which recieves a Button
object and the active button Id as arguments. The SetActiveButton
method just becomes of bunch of calls to SetButtonState
, one for each button in the menu.
Using the MenuUserControl
In some parent control, most likely Site.master
, add a reference to the MenuUserControl in the Design file:
<%@ Register Src="~/UserControls/MenuUserControl.ascx"
tagname="ButtonList" tagprefix="Menu" %>
Then add the menu user control itself:
<body>
<div id="page">
<Menu:ButtonList ID="MainMenu" runat="server" />
Lastly, in the Code-Behind for Site.master
call the SetActiveButton
method on the menu user control:
public partial class SiteMaster : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
MainMenu.SetActiveButton((string)Session["whichTopMenu"]);
}
}
Conclusion
This approach has several benefits:
- The code is more DRY (Don't Repeat Yourself)
- All presentation logic is in C#, where it belongs
- By creating a user control just to encapsulate this menu, you've created something that you can reuse if necessary
- The logic for setting button text and the "active" state lies in C#, allowing you to leverage Intellisense in Visual Studio. Code errors are easier to catch, plus you can use the refactoring tools easier in Visual Studio should anything change in the future.
An Alternative: Using <asp:Repeater />
You might also try using the <asp:Repeater />
control instead of a table in the MenuUserControl. You can build your menu items dynamically in C#, but I leave that as a research topic for you.