Il mio suggerimento sarebbe quello di estrarre tutti i controlli inclusi questo UpdatePanel da questo UpdatePanel in un UserControl. Definisci gli eventi nel tuo usercontrol che vengono generati quando si fa clic sui pulsanti o quando viene modificato l'indice selezionato di Dropdown. Gestisci questi eventi nella tua pagina che contiene il segnaposto (in un singolo UpdatePanel, condizionale, senza trigger). Chiamare manualmente il metodo di aggiornamento del pannello di aggiornamento principale se si aggiungono UserControls.
Per chiarire ciò che intendo dare un'occhiata al seguente esempio:
Main-pagina aspx:
<asp:UpdatePanel ID="Upd1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
Codebehind:
Private Property UserControlCount() As Int32
Get
If ViewState("UserControlCount") Is Nothing Then
ViewState("UserControlCount") = 1
End If
Return DirectCast(ViewState("UserControlCount"), Int32)
End Get
Set(ByVal value As Int32)
ViewState("UserControlCount") = value
End Set
End Property
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
recreateUserControls()
End Sub
Private Sub recreateUserControls()
For i As Int32 = 1 To Me.UserControlCount
Dim uc As DynamicControls = DirectCast(Me.LoadControl("DynamicControls.ascx"), DynamicControls)
uc.ID = "DynamicControls_" & i
Addhandlers(uc)
Me.PlaceHolder1.Controls.Add(uc)
Next
End Sub
Private Sub Addhandlers(ByVal uc As DynamicControls)
AddHandler uc.asyncButton1Clicked, AddressOf ucAsyncButton1Clicked
AddHandler uc.asyncButton2Clicked, AddressOf ucAsyncButton2Clicked
AddHandler uc.syncButtonClicked, AddressOf ucSyncButtonClicked
AddHandler uc.asyncDropDownSelectedIndexChanged, AddressOf ucAsyncDropDownSelectedIndexChanged
End Sub
Private Sub addUserControl()
Me.UserControlCount += 1
Dim uc As DynamicControls = DirectCast(Me.LoadControl("DynamicControls.ascx"), DynamicControls)
uc.ID = "DynamicControls_" & Me.UserControlCount
Addhandlers(uc)
Me.PlaceHolder1.Controls.Add(uc)
Upd1.Update()
End Sub
Private Sub ucAsyncButton1Clicked(ByVal sender As Object, ByVal e As EventArgs)
'only to demonstrate how to add control dynamically and update the UpdatePanel'
addUserControl()
Me.Upd1.Update()
End Sub
Private Sub ucAsyncButton2Clicked(ByVal sender As Object, ByVal e As EventArgs)
End Sub
Private Sub ucSyncButtonClicked(ByVal sender As Object, ByVal e As EventArgs)
End Sub
Private Sub ucAsyncDropDownSelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
End Sub
ascx che tiene la vostra comandi:
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="DynamicControls.ascx.vb" Inherits="AJAXEnabledWebApplication1.DynamicControls" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<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" />
<asp:DropDownList ID="asyncDropDown" runat="server" AutoPostBack="true" />
<asp:Button ID="asyncButton2" runat="server" Text="Button2" />
<asp:Button ID="syncButton" runat="server" Text="SyncButton" />
</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>
Codebehind di UserControl:
Public Partial Class DynamicControls
Inherits System.Web.UI.UserControl
Public Event asyncButton1Clicked(ByVal sender As Object, ByVal e As System.EventArgs)
Public Event asyncButton2Clicked(ByVal sender As Object, ByVal e As System.EventArgs)
Public Event syncButtonClicked(ByVal sender As Object, ByVal e As System.EventArgs)
Public Event asyncDropDownSelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Private Sub asyncButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles asyncButton1.Click
RaiseEvent asyncButton1Clicked(sender, e)
End Sub
Private Sub asyncButton2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles asyncButton2.Click
RaiseEvent asyncButton2Clicked(sender, e)
End Sub
Private Sub syncButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles syncButton.Click
RaiseEvent syncButtonClicked(sender, e)
End Sub
Private Sub asyncDropDown_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles asyncDropDown.SelectedIndexChanged
RaiseEvent asyncDropDownSelectedIndexChanged(sender, e)
End Sub
End Class
In questo modo non avrete problemi con ClientID di.
Aggiunta: Se è necessario accedere ai controlli delle tue UserControls in caso-gestori, utilizzare una delle seguenti due opzioni:
- gettato NamingContainer del mittente per il tipo di UserControl:
Dim uc As DynamicControls = DirectCast(DirectCast(sender, Control).NamingContainer, DynamicControls)
sostituire tutte le occorrenze di (ByVal sender As Object, ByVal e As System.EventArgs)
con (uc as DynamicControls)
. Su questo modo si aggiunge il riferimento del vostro UserControl per l'evento come parametro e si può accedere alle proprietà pubbliche dalla pagina, fe:
dim txt1 as String = uc.Text1
Se è stata esposta una proprietà Testo1 nella UserControl:
Public Property Text1() As String
Get
Return textBox1.Text
End Get
Set(ByVal value As String)
textBox1.Text = value
End Set
End Property
La seconda opzione è il modo più pulito e più leggibile.
Aggiornamento: Secondo il vostro commento: è necessario posizionare l'UpdateProgress nella UserControl all'interno del UpdatePanel che viene aggiornato. Ricordarsi di impostare AssociatedUpdatePanelID correttamente. Ad esempio:
<asp:UpdatePanel ID="UdpForm" runat="server" UpdateMode="conditional" ChildrenAsTriggers="false" >
<ContentTemplate>
<asp:panel ID="FormPanel" runat="server">
<asp:UpdateProgress ID="UpdateProgress1" DynamicLayout="true" runat="server" AssociatedUpdatePanelID="UdpForm" DisplayAfter="0" >
<ProgressTemplate>
<div class="progress">
<asp:Image ID="ImgProgress1" runat="server" ImageUrl="~/images/ajax-loader-arrows.gif" ToolTip="loading..." /> please wait...
</div>
</ProgressTemplate>
</asp:UpdateProgress>
<asp:FormView ID="FormView1" runat="server" DefaultMode="ReadOnly" >
<ItemTemplate></ItemTemplate>
<EditItemTemplate></EditItemTemplate>
<InsertItemTemplate></InsertItemTemplate>
<EmptyDataTemplate>
</EmptyDataTemplate>
<PagerTemplate >
</PagerTemplate>
</asp:FormView>
</asp:panel>
</contenttemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdContent" runat="server" UpdateMode="conditional" ChildrenAsTriggers="false" >
<ContentTemplate>
<asp:Panel ID="PnlMain" runat="server">
<asp:UpdateProgress ID="UpdateProgress2" DynamicLayout="true" runat="server" AssociatedUpdatePanelID="UpdContent" DisplayAfter="0" >
<ProgressTemplate>
<div class="progress">
<asp:Image ID="ImgProgress1" runat="server" ImageUrl="~/images/ajax-loader-arrows.gif" ToolTip="loading..." /> please wait...
</div>
</ProgressTemplate>
</asp:UpdateProgress>
Content
</asp:Panel>
</ContentTemplate>
<Triggers ></Triggers>
</asp:UpdatePanel>
Si sta utilizzando .net framework 4.0? Chiedo perché ora hai più controllo su Control.ClientID: http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientid.aspx –
@Tim No, questo deve essere. NET 3.5 per ora. – Andrew
taggato come 3.5. Vado a dare un'occhiata da vicino più tardi. –