2011-01-31 14 views
12

En una página contiene dos UpdatePanels, ¿cómo puedo saber qué UpdatePanel causa el PostBack parcial?¿Determinar qué UpdatePanel causa el PostBack parcial (asincrónico)?

Me refiero al controlador de eventos Page_Load.

Este es mi código:

<asp:ScriptManager ID="ScriptManager1" runat="server"> 
</asp:ScriptManager> 
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" 
    onprerender="UpdatePanel1_PreRender"> 
    <ContentTemplate> 
     <A:u1 ID="u1" runat="server" /> 
    </ContentTemplate> 
</asp:UpdatePanel> 
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional" 
    onprerender="UpdatePanel2_PreRender"> 
    <ContentTemplate> 
     <A:u2 ID="u2" runat="server" /> 
    </ContentTemplate> 
</asp:UpdatePanel> 

yo probamos este código, pero no se trabaja alost!

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack) 
    { 
     if (UpdatePanel1.IsInPartialRendering) 
     { 
      // never enter to here 
     } 
     if (UpdatePanel2.IsInPartialRendering) 
     { 
      // neither here 
     } 
    } 
} 

¡Cualquier ayuda!

Respuesta

10

Usted puede utilizar la propiedad IsInPartialRendering de la clase UpdatePanel para determinar si un panel específico causó la devolución parcial:

protected void Page_Render(object sender, EventArgs e) 
{ 
    if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack) { 
     if (yourFirstUpdatePanel.IsInPartialRendering) { 
      // The first UpdatePanel caused the partial postback. 
     } else if (yourSecondUpdatePanel.IsInPartialRendering) { 
      // The second UpdatePanel caused the partial postback. 
     } 
    } 
} 

EDIT: Parece queIsInPartialRendering es siempre false antes de la fase Render. Como desea esa información durante la fase Load, no funcionará como se esperaba. Ver this bug.

Hay una solución documented here que consiste en derivar su propia clase de UpdatePanel para acceder a su protegida RequiresUpdate propiedad:

public class ExtendedUpdatePanel : UpdatePanel 
{ 
    public bool IsUpdating 
    { 
     get { 
      return RequiresUpdate; 
     } 
    } 
} 

Después de reemplazar asp:UpdatePanel con ExtendedUpdatePanel en su página de marcado, el código anterior se convierte en:

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack) { 
     if (yourFirstUpdatePanel.IsUpdating) { 
      // The first UpdatePanel caused the partial postback. 
     } else if (yourSecondUpdatePanel.IsUpdating) { 
      // The second UpdatePanel caused the partial postback. 
     } 
    } 
} 
+0

¡Lo probé, no funcionó! – Homam

+0

@John, ¿cuál es el comportamiento que observas? ¿Recibió un mensaje de error? –

+0

No, pero no se ingresa si stetement nunca. – Homam

7

Pruebe esto:

ScriptManager.GetCurrent().AsyncPostBackSourceElementID 
+3

Esto resolvió mi problema. Utilicé una sentencia if como esta: if (ScriptManager.GetCurrent (Página) .IsInAsyncPostBack && ScriptManager.GetCurrent (Página) .AsyncPostBackSourceElementID == control.UniqueID) - necesita comparar el UniqueID no ClientID y si su panel de actualización contiene más de un control necesitarás probar para cada uno de ellos. – johna

+0

Para mí esa propiedad devuelve el id de un botón ... – Peter

5

Si no desea extender la clase UpdatePanel original, también se puede utilizar esta solución:

string id = ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID; 

Por lo tanto, se puede examinar el identificador resultante y añadir algunas cláusulas condicionales para determinar qué código debe ejecutar. Esta identificación debe ser igual al primer parámetro que se pasó a través de la función javascript __doPostBack('someid', '').

Por ejemplo, tengo un control de usuario en mi panel de actualización:. Este control contiene un montón de botones de enlace que desencadenan el UpdatePanel) También puede actualizar manualmente este panel de algunos enlaces externos (usando algo como __doPostBack('myUpdatePanelClientId', '');

es decir, en mi caso, veo tres formas diferentes para cargar mi UpdatePanel:

  • carga de la página Primera;
  • botón de Enlace (o cualquier otro tipo de botón) hace clic dentro de mi UpdatePanel;
  • PostBack activado fuera de UpdatePanel.

Cada situación me da una identificación diferente. El primero me da una cadena vacía (ya que esta es la primera carga de la página, no ha habido ninguna devolución de datos activada con la función __doPostBack.)

El segundo me da la ID Única del botón que fue empujado dentro del control de usuario (este es el original y el comportamiento esperado de ASP.NET.)

El tercero me da exactamente lo que pasa como el primer argumento cuando codifiqué el método (es decir: el Id. de cliente del Panel de actualización)

Así fue como logré implementar mi caso de uso de UpdatePanel (suponiendo que estoy usando el modo de representación parcial). Esto no es perfecto, pero funciona Como era la intención.

protected void myUpdatePanel_Load(object sender, EventArgs e) 
{ 
    string id = ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID; 

    bool firstLoad = (String.IsNullOrEmpty(id)); 
    bool triggerFromUpdatePanel = !firstLoad && (id.Contains(userControlInsideMyUpdatePanel.UniqueID)); 
    bool triggerFromExternalControl = !firstLoad && (id == myUpdatePanel.ClientID); 

    // case 1, 2, 3. 
    if ((firstLoad) || (triggerFromUpdatePanel) || (triggerFromExternalControl)) 
    { 
     // do something 
    } 
    else 
    { 
     // do nothing! 
    } 


} 
0

Si el asyncpostbackelementid se establece a continuación, se puede comprobar que uniqueid de UpdatePanel que inicia con la identificación, lo que significa que está dentro de él desde UpdatePanels se inaming contenedores.

-1

es posible determinar el objeto dentro de un panel de actualización un ejecutar el código necesario

If (ScriptManager.GetCurrent(Page).IsInAsyncPostBack) Then 
       Dim id As String = ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID 
       Dim Obj = UpdatePanel1.FindControlRecursive(id) 
       If Not IsNothing(Obj) Then 
        a = 1 
       End If 
End If 

por debajo de la función que se utiliza para encontrar de objeto dentro del panel de actualización. Es una extensión de System.Web.UI.Control

a = 1 Es el código deseado.

Public Module thisExtensions 
     <System.Runtime.CompilerServices.Extension> _ 
     Public Function FindControlRecursive(control As System.Web.UI.Control, id As String) As System.Web.UI.Control 
      If control Is Nothing Then 
       Return Nothing 
      End If 
      'try to find the control at the current level 
      Dim ctrl As Control = control.FindControl(id) 

      If ctrl Is Nothing Then 
       'search the children 
       For Each child As Control In control.Controls 
        ctrl = FindControlRecursive(child, id) 

        If ctrl IsNot Nothing Then 
         Exit For 
        End If 
       Next 
      End If 
      Return ctrl 
     End Function 
    End Module 
0

En cliente uso lado:

función EndRequestHandler (remitente, args) { si (Sys.WebForms.PageRequestManager.getInstance() ._ postBackSettings.asyncTarget == 'Id de elemento no devolución de datos') { // hacer algo. . . } } Sys.WebForms.PageRequestManager.getInstance(). Add_endRequest (EndRequestHandler);

Cuestiones relacionadas