Mental Jetsam

By Peter Finch

Archive for April 4th, 2007

Using a Microsoft Atlas UpdatePanel on Master Pages with multiple ContentPlaceHolders

Posted by pcfinch on April 4, 2007

ASP.NET Atlas Master Page StructureThis scenario is pretty straight forward. You have a MasterPage with 2 ContentPlaceHolders, one for the menu on the left and one for the content on the right (A simple label in this case). When you select a menu item on the left you want to update the content page on the right using AJAX.

Normally, all you have to do to accomplish this is to add an Atlas UpdatePanel.

1. Add the ScriptManager to the MasterPage.

<asp:scriptmanager id="scriptmanager1" runat="server"></asp:scriptmanager>

2. Add the UpdatePanel to the corresponding Content section of the Content page

3. Add the controls to the UpdatePanel that you want to update using AJAX.

4. Add a Trigger to the UpdatePanal that references the control (e.g. Menu1) and the event (e.g. MenuItemClick). This can be done manually in the HTML source view or from the Triggers field, in the Behavior properties section.

<asp:AsyncPostBackTrigger ControlID="Menu1" EventName="MenuItemClick"></asp:AsyncPostBackTrigger>

Normally, with Atlas, this is all you have to do, however, when using Master Pages you will get an error on the page something like this.

A control with ID 'Menu1' could not be found for the trigger in UpdatePanel 'UpdatePanel1'.]

The reason for this message is that Controls in Content pages of Master pages do not actually have their original ID’s. For example, although Menu1’s ID is “Menu1” it’s actual UniqueID is something like “ctl00$Menu$Menu1”. The real problem is that you do not know this until runtime. You could add a AsyncPostBackTrigger() manually to the UpdatePanel.Triggers collection at runtime in the OnInit() function using static strings, but this is not very maintainable.

The following method simply looks through the triggers on the UpdatePanel and for the one that ends with the ID of the Menu1 control it simply changes the trigger ControlID to the UniqueID of Menu1 as runtime. This MUST happen in the OnInit() method of the Content Page. Although you have to hardcode the Menu1 item (and any other trigger controls), it means that you can change the Menu’s ID or even the EventName without having to touch the code.

protected override void OnInit(EventArgs e)
   foreach (AsyncPostBackTrigger apbt in UpdatePanel1.Triggers) {
      if (Menu1.UniqueID.EndsWith(apbt.ControlID))
         apbt.ControlID = Menu1.UniqueID;

Posted in C#.NET | 10 Comments »