Thursday 4 September 2008

Collapsing the AjaxToolkit CollapsiblePanelExtender from server code

Well, this one had me going for quite some time so I just thought I'd share my solution with you :-)

First off, i'm tired of typing CollapsiblePanelExtender, so from here on in it's a CPE!

Secondly setting the Collapsed and ClientState on the CPE properties do not work a unless the page/control containing the CPE is refreshed with a postback, which in this scenario it is not.

Imagine, you have page called MyPage.aspx. This has a control called MyControl.ascx on it. MyControl.ascx has a CPE on it called MyCPE. MyCPE has a usercontrol on it (called MyDetails.ascx). MyDetails.ascx has a number of controls on it, but one of them is a 'Cancel' button. You want this to collapse the panel (This is in addition to the CollapseControl already assigned to the CPE). Phew, that's quite a heirarchy, but it's simpler than the one I had to work with!!

There are two main stages to this solution:

First - Wire up events
Wire up the OnClick event of the aforementioned 'Cancel' button to the parent page/control. So if the page MyPage.aspx has a control on it called MyControl.ascx, and this control has MyCPE on it. MyCPE has MyDetails.ascx on it, and MyDetails.ascx has the cancel button on it.

MyControl needs to have an event handler which is fired when the OnClick event is fired on MyDetails.ascx. To acheive this, modify your code something like;

MyControl.ascx.cs

Add the following line to the Page_Load event:

this.MyDetails.CanclButtonHasBeenClicked += CancelButtonClicked

Add the following empty event handler (we'll populate it later):

private void CancelButtonClicked(object sender, EventArgs e)
{
}

MyDetails.ascx.cs

Publicly expose the Cancel OnClick event by adding a public event handler to the class

Public EventHandler CancelButtonHasBeenClicked;

Fire your new event handler when the cancel button is clicked. Add the following to the actual event handler for the cancel button:

CancelButtonHasBeenClicked(sender, e);

Second - Collapse the CPE

Ok, now your parent user control (MyControl.ascx) is notified when the cancel button is clicked on the CPE (via the MyDetails.ascx control). Now you just need to inject some javascript to collapse the CPE. Add the following code to the empty CancelButtonClicked event handler created above:

string JavaScriptCode="$find('MyCPEBehaviour').collapsePanel();";
ScriptManager.RegisterStartupScript(Page, Page.GetTpye(),"MyScript",JavaScriptCode,true);

Thanks to James Ashley who pointed me on the right direction on that one!

Finally, add the behaviour id to your CPE in MyControl.ascx by adding the following to the CPE tag:

BehaviorID="MyCPEBehaviour"

Job Done. Now your CPE should collapse when you click on the 'Cancel' button on MyDetails.ascx within the CPE on MyControl.ascx.

Hopefully this waffle makes some sense and helps someone one day...

No comments: