I'm looking to use the AccordionExtender as a navigation menu in a master page.
I want to save / read the AccordionExtender SelectedIndex property across PostBacks, in order to keep the same accordion pane open after PostBack.
I'm wondering why the add_selectedIndexChanged() client-side function doesn't work to add an event handler. Instead, I've had to call my own function on click or mouseover.
Why the server-side SelectedIndex property doesn't hold the currently selected index, I don't understand (it would make this a lot easier). As it doesn't, I was forced, like many others, to implement a solution to pass the SelectedIndex property from the client-side to the server-side, and then to save and restore it.
Some have suggested a cookie or session variable to store the selected index; I chose the session variable. Some have suggested a hidden field or textbox to pass the index value from client to server, but I found it always to be null on PostBack after setting the value on the client-side.
A full PostBack on every SelectedIndex change isn't desirable, so I implemented a Callback event, which requires the code to sit on the server-side, where Page.ClientScript.GetCallbackEventReference() can be called.
I have the following code, which works, but I'd prefer to bind an event handler directly to the selectedIndexChanged event. I tried various uses of $get and $find to get the AccordionExtender object to use with $addhandler, but none result in an object that allows binding to the selectedIndexChanged event.
The commented code below seems as though it should work to add the event handler, but doesn't.
Note that accLeftNav is the AccordianExtender object.
1 public partial class Site : System.Web.UI.MasterPage, System.Web.UI.ICallbackEventHandler
2 {
3 public void RaiseCallbackEvent(String eventArgument)
4 {
5 // Processes a callback event on the server using the event argument from the client.
6 if (!String.IsNullOrEmpty(eventArgument))
7 Session["LeftNavSelectedIndex"] = eventArgument;
8 }
9
10 public string GetCallbackResult()
11 {
12 // Returns the results of a callback event to the client.
13 return String.Empty;
14 }
15
16 protected void Page_Load(object sender, EventArgs e)
17 {
18 if (Session["LeftNavSelectedIndex"] != null)
19 {
20 int selectedIndex = 0;
21 Int32.TryParse(Session["LeftNavSelectedIndex"].ToString(), out selectedIndex);
22 accLeftNav.SelectedIndex = selectedIndex;
23 }
24
25 if (!Page.IsPostBack)
26 {
27 for (int i = 0; i < accLeftNav.Panes.Count; i++)
28 {
29 accLeftNav.Panes[i].HeaderContainer.Attributes.Add("onclick", String.Format("javascript:LeftNavCallback({0}, 'click');", i));
30 accLeftNav.Panes[i].HeaderContainer.Attributes.Add("onmouseover", String.Format("javascript:LeftNavMouseOver({0}, 'mouseover');", i));
31 }
32
33 // Doesn't work - add_selectedIndexChanged() isn't found for the object
34 //ScriptManager.RegisterStartupScript(this, this.GetType(), "RegisterLeftNavCallback", String.Format("var leftNav = $find('{0_AccordionExtender}'); leftNav.add_selectedIndexChanged(LeftNavServerCallback);", accLeftNav.ClientID), true);
35
36 // See: Implementing Client Callbacks Programmatically Without Postbacks in ASP.NET Web Pages - http://msdn.microsoft.com/en-us/library/ms178208.aspx
37 // And: How to: Implement Callbacks in ASP.NET Web Pages - http://msdn.microsoft.com/en-us/library/ms366518.aspx
38 String strCallbackEventReference = Page.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "");
39 String strCallbackScript = String.Format("function LeftNavCallback(arg, context) {{ {0}; }}", strCallbackEventReference);
40 ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "LeftNavCallback", strCallbackScript, true);
41 ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "ReceiveServerData", "function ReceiveServerData(arg, context) { }", true);
42 ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "LeftNavMouseOver", String.Format(
43 "function LeftNavMouseOver(arg, context) {{ $find('{0}_AccordionExtender').set_SelectedIndex(arg); LeftNavCallback(arg, context); }}",
44 accLeftNav.ClientID), true);
45 }
46 }
47 }