I have a page with a ScriptManager, a generic HTML drop-down list (<select>
), and an UpdatePanel. The UpdatePanel contains a PlaceHolder (for now). During Page_Load, a number of user controls are added to the PlaceHolder (really, it's several instances of the same user control). The number to add is not known until the page loads, so they do need to be loaded dynamically. The drop-down list is populated with the same number of menu items, and there is javascript on the page also (using jQuery) to show only one of the controls at a time depending on the state of the drop-down list.
Each user control has two buttons that should generate an asynchronous postback, a drop-down list that should generate an asynchronous postback on a change in selected value, and a button that should generate a synchronous postback. If I was not generating the controls dynamically, and if there was only one control, the structure would be something like:
<asp:UpdatePanel ID="myUpdatePanel" runat="server" UpdateMode="Conditional"
ChildrenAsTriggers="false">
<ContentTemplate>
<asp:TextBox ID="textBox1" runat="server" />
<asp:TextBox ID="textBox2" runat="server" />
<asp:Button ID="asyncButton1" runat="server" Text="Button1"
onclick="asyncButton1_Click" />
<asp:DropDownList ID="asyncDropDown" ruant="server" AutoPostBack="true"
OnSelectedIndexChanged="asyncDropDown_SelectedIndexChanged" />
<asp:Button ID="asyncButton2" runat="server" Text="Button2"
OnClick="asyncButton2_Click" />
<asp:Button ID="syncButton" runat="server" Text="SyncButton"
OnClick="syncButton_Click" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="asyncButton1" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="asyncButton2" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="asyncDropDown"
EventName="SelectedIndexChanged" />
<asp:PostBackTrigger ControlID="syncButton" />
</Triggers>
</asp:UpdatePanel>
Of course, all the controls inside the ContentTemplate would actually be part of each user control.
Adding the triggers on the server side does not seem to work because no ControlID seems to help the UpdatePanel find the relevant controls. I can use either the control's ID or the control's UniqueID, and it does not work, and I get an error along the lines of
A control with ID 'ctl00$ContentPlaceHolder1$ctl01$asyncButton1' could not be
found for the trigger in UpdatePanel 'myUpdatePanel'.
So, I wonder if I need to register the triggers in the client instead using ASP.NET Ajax. I found this page that basically explains how. However, I do not know how to get the EventName taken into consideration. The examples I have seen so far have merely been adding button clicks, but I don't know how to handle the SelectedIndexChanged event from the DropDownList.
Any help here? Are there examples out there I have missed? It doesn't help, of course, that the method in the link I gave appears to be "unofficial," so I don't see any MSDN documents on the subject.
Thanks!
My suggestion would be to pull all your controls inclusive this UpdatePanel out of this UpdatePanel into an UserControl. Define events in your usercontrol that are raised when the buttons are clicked or the Dropdown's selected index get changed. Handle these events in your page that holds the Placeholder(in a single UpdatePanel,conditional,without triggers). Call the Update-method of the main update panel manually if you add UserControls.
To clarify what i mean have a look at following example:
Main-page aspx:
Codebehind:
ascx which holds your controls:
Codebehind of UserControl:
On this way you won't have problems with ClientID's.
Addition: If you need access to the controls of your UserControls in the event-handlers, use one of following two options:
Dim uc As DynamicControls = DirectCast(DirectCast(sender, Control).NamingContainer, DynamicControls)
replace all occurences of
(ByVal sender As Object, ByVal e As System.EventArgs)
with(uc as DynamicControls)
. On this way the reference of your UserControl is added to the event as parameter and you could access public properties of it from the page, f.e.:If you have exposed a property Text1 in the UserControl:
The second option is the cleanest and most readable way.
Update: According to your comment: you should place the UpdateProgress in the UserControl inside of the UpdatePanel that gets updated. Remember to set the AssociatedUpdatePanelID correctly. For example: