WebPageMaster Project w/Accordian Menu Download (959.90 kb)
Screen Shot (29.41 kb)
Master Pages (2nd of a Series)
Just when you thought is was plug-in-play from here on in and adding a control is now starting to be a flippin', nested hassle... and you're ready to say 'screw this', hold on...
So, you downloaded the Ajax Control Toolkit to be part of your Visual Studio environment and found that the Accordion Control is a cool one and it should be used in the side menu (in the MasterPage demo project of the previous article). So you gave it a whirl, and the damn thing ain't working as expected. Again, this is due to how MasterPages are assembled and work. Now, let's put the frustration aside and read on...
the Definition: The way we want it to work
Let's say to start with, is that when you open a link from a pane which is not a default pane of the accordion control, you want it to remain open (which it won't, yet). Second, if you go to another main menu option and return to this one, you would like to see the pane which was last opened, which launched a link in that pane.
Here, we will try to make it simple (and it is).

When the user launches Sales Orders or Sales Invoices, the Receivables pane will now be the default open pane for the session. This default will change as the user launches other menu items from other panes.
Just a note, code was added to the style sheet /MasterStuff/Styles.css for the visual effects and this was appended under the comment /* Accordion Control */ in the new project download above.
the Accordion Control: from the Ajax Control Tookit
This is the Accordion control that was added to the file: [AcctMenu.Master], don't forget to register the assembly for the AjaxControlToolkit on the top of the page...
<%@ Master Language="C#" MasterPageFile="~/MasterStuff/Site.master" CodeFile="~/MasterStuff/AcctgMenu.master.cs" Inherits="AcctgMenu"%>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajx" %>
<asp:Content id="Content1" ContentPlaceholderID="ChildContent" runat="server">
<div id="R_mainWrapper"><asp:ContentPlaceHolder id="MainContent" runat="server" /></div>
<div id="leftContent">
<p style="text-align: center;">
<asp:Label ID="DateDisplay" runat="server"></asp:Label>
</p>
<h3>Accounting Menu</h3>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<ajx:Accordion ID="AccountingMenu" runat="server" TransitionDuration="250" FramesPerSecond="40"
FadeTransitions="true"
HeaderCssClass="acc-header" ContentCssClass="acc-content" HeaderSelectedCssClass="acc-selected"
SuppressHeaderPostbacks="true">
<Panes>
<ajx:AccordionPane ID="AccordionPane1" runat="server" >
<Header> Main</Header>
<Content>
<ul class="SideUl">
<li>
<asp:LinkButton ID="lnkb1" runat="server" OnClick="MenuLinkButton_OnClick"
CommandArgument="AcctgHome.aspx" Text="Accounting Home" />
</li>
<li>
<asp:LinkButton ID="lnkb2" runat="server" OnClick="MenuLinkButton_OnClick"
CommandArgument="AcctgAbout.aspx" Text="About Accounting" />
</li>
</ul>
</Content>
</ajx:AccordionPane>
<ajx:AccordionPane ID="AccordionPane2" runat="server">
<Header> Receivables</Header>
<Content>
<ul class="SideUl">
<li>
<asp:LinkButton ID="lnkb3" runat="server" OnClick="MenuLinkButton_OnClick"
CommandArgument="SO.aspx" Text="Sales Order" /></li>
<li>
<asp:LinkButton ID="lnkb4" runat="server" OnClick="MenuLinkButton_OnClick"
CommandArgument="SI.aspx" Text="Sales Invoice" />
</li>
</ul>
</Content>
</ajx:AccordionPane>
<ajx:AccordionPane ID="AccordionPane3" runat="server">
<Header> Payables</Header>
<Content>
<ul class="SideUl">
<li>
<asp:LinkButton ID="lnkb5" runat="server" OnClick="MenuLinkButton_OnClick"
CommandArgument="PO.aspx" Text="Purchase Order" /></li>
<li>
<asp:LinkButton ID="lnkb6" runat="server" OnClick="MenuLinkButton_OnClick"
CommandArgument="PI.aspx" Text="Purchase Invoice" />
</li>
</ul>
</Content>
</ajx:AccordionPane>
</Panes>
</ajx:Accordion>
</div>
</asp:Content>
This is the server-side code in: [AcctMenu.Master.cs]
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class AcctgMenu : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
DateDisplay.Text = DateTime.Now.ToString("dddd, MMMM dd");
if (!IsPostBack)
{
if (Session["accAccounting.SelectedIndex"] != null)
{
AccountingMenu.SelectedIndex = (int)Session["accAccounting.SelectedIndex"];
}
}
}
public void SaveMenuIndex()
{
Session["accAccounting.SelectedIndex"] = AccountingMenu.SelectedIndex;
}
public void MenuLinkButton_OnClick(object sender, EventArgs e)
{
SaveMenuIndex();
Response.Redirect(((LinkButton)sender).CommandArgument);
}
}
the Way this thing works:
- Page_Load() - the session variable 'accAccounting.SelectedIndex' is checked to see if it exists and if it has been set. If not, it will use whatever was set in the control as the default. Otherwise it will use the session variable to open the desired pane.
- MenuLinkButton_OnClick() - this is called whenever a menu item was launched (you can see that this event was added to all the LinkButtons in the Accordion control). The first thing that happens is SaveMenuIndex() is called which will set the session variable, then the link is launched.
- SaveMenuIndex() - this function sets/creates the session variable whenever it is called with the value of Accordion Control selected pane. In our case, it is only when a menu item is launched.
The key: is using a session variable for the departmental menu, we didn't want to use cookies in case the user's browser had them turned off. Also, we chose this method in case we decide on generating these menus dynamically and we now know what's needed (the OnClick event in the LinkButton).
You can now add this Accordion control to other departmental.master's menus ...even if it only has a single pane in order to maintain the style used throughout the entire site (who knows you may need to add another pain in the future (ah... we mean pane) to the control).
Screen Shot (29.41 kb)
WebPageMaster Project w/Accordian Menu Download (959.90 kb)
the WebPepper team