2011-10-31 14 views
6

Tengo un GridView en un panel de actualización. Es un asp heredado: GridView, por lo que tiene un pequeño icono de "exportarme" que hace precisamente eso. Funciona respondiendo a un clic de "exportación" con un archivo XLS. El problema es que si coloca el GridView inteligente dentro de un panel de actualización, ASP.NET piensa que el archivo XLS debe escribirse en el panel, que obviamente no es lo que queremos. Para esto, necesito un post-back completo cada vez.Forzar devolución de datos completa programáticamente desde UpdatePanel

Mis paneles de actualización están todos programáticamente generado

soluciones que no funcionan en este escenario preciso (muchos de los cuales están cubiertos en otra parte de SO):

  1. En ASP.NET antes de la versión 4 Si deja la ID fuera de control, realizará una devolución de datos completa incluso desde un panel de actualización. Mi pregunta es para el último y más grande .NET 4 solamente.

  2. ScriptManager.RegisterPostBackControl parece prometedor. Hace que el control posterior a la devolución use la ID del panel correcto como objetivo del evento, pero de lo contrario no ayuda.

  3. Agregando un PostBackTrigger al panel Actualizar. Mis paneles de actualización se generan mediante programación, y MS indica que esto no es compatible. Mis pruebas indican que tienen razón: lo intenté de todos modos, pero esto no funciona.

  4. Realmente no me gusta la idea de que el Smart GridView tenga que salir de sí mismo, pero traté de hacerlo poner un control extra fuera del updatePanel en estas circunstancias. La idea de hacer que un cliente haga clic en mi botón exportar dentro del panel sea redirigido por javascript del cliente para simular un clic en ese botón fuera del panel. Sin embargo, esto no funciona porque aparentemente no puedo agregar el control "externo" a la página. Obtengo el mensaje "La colección de control no se puede modificar durante las fases de DataBind, Init, Load, PreRender o Unload". error.

  5. Usando jQuery para cambiar el control de "exportación" fuera del panel. MS debe tener una lista de controles que creen que están "en" el panel, y la ubicación física dentro del DOM no importa.

¿Alguien tiene alguna idea de cómo hacer que funcione? Sé mucho de esto debería funcionar, pero eso no es exactamente lo mismo.

Respuesta

4

Para mí, la solución 3 funciona.

Agregué dinámicamente un UpdatePanel a la página, agregué un Button a la plantilla de contenido y asocié un PostBackTrigger. Agregué un controlador de eventos Click en el que actualizo una etiqueta (fuera del UpdatePanel) con la fecha/hora actual.

Vea la configuración de mi prueba a continuación.

marcado

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager> 
<asp:Panel ID="Panel1" runat="server"></asp:Panel> 
<asp:Label ID="Label1" runat="server"></asp:Label> 

Código Detrás

protected void Page_Load(object sender, EventArgs e) 
{ 
    string buttonId = "Button1"; 

    UpdatePanel updatePanel = new UpdatePanel(); 
    updatePanel.ID = "UpdatePanel1"; 

    Button button = new Button(); 
    button.ID = "Button1"; 
    button.Text = "Post back"; 
    button.Click += new EventHandler(button_Click); 

    updatePanel.Triggers.Add(new PostBackTrigger() { ControlID = buttonId}); 

    updatePanel.ContentTemplateContainer.Controls.Add(button); 

    Panel1.Controls.Add(updatePanel); 
} 

void button_Click(object sender, EventArgs e) 
{ 
    Label1.Text = string.Format("Current date/time: {0}", DateTime.Now.ToString()); 
} 

Espero que esto ayude.

+0

No funciona de esa manera para mí. Si agrego el "postBackTrigger" cuando creo los paneles, falla si el button.ID aún no está presente (razonable), pero si lo agrego en mi control personalizado no tiene ningún efecto - sugiere algo de ciclo de vida . Me quedaré con eso. – philw

+0

Si pongo el control del botón en la página en OnInit() del control que contiene los paneles de actualización, funciona como se sugiere. Si en cambio lo coloco donde lo necesito, en el OnInit() del control personalizado dentro del panel (buscando una copia de seguridad de la jerarquía de control para encontrar el panel de actualización), entonces no funciona. Más experimentación .. – philw

+0

No estoy seguro si esto ayudará, pero revise esta pregunta (específicamente la respuesta): [FileUpload en FormView dentro de un UpdatePanel] (http://stackoverflow.com/questions/3555917/fileupload-in-formview-inside -an-updatepanel) – jdavies

0

Creé un control GridView heredado similar con la capacidad de exportar CSV. La forma en que lo manejé es hacer que el botón de exportación sea simple <a href> en la página actual con un parámetro de cadena de consulta especialmente diseñado "?SortablePagableGridViewExportToCSV=XXX" donde XXX es el UniqueID de mi control. Anulo el método Render de mi control, y allí verifico manualmente los parámetros de solicitud para ver si se envió ese parámetro de exportación. Si es así, escribo el encabezado y la respuesta del tipo de contenido CSV como se muestra a continuación.

Me.Page.Response.Clear() 
Me.Page.Response.ClearContent() 
Me.Page.Response.ClearHeaders() 
Me.Page.Response.ContentType = "text/csv" 
Me.Page.Response.AddHeader("Content-Disposition", "attachment;filename=" & Me.ExportToCsvFileName) 
Me.Page.Response.End() 

La clave es la llamada a Page.Response.End(), que se detiene todo el procesamiento posterior. Esta es una solicitud GET, así que no tengo que preocuparme por las devoluciones de datos de asincronización de UpdatePanel ni nada de eso. El navegador se comporta maravillosamente en esta situación, apareciendo el enlace de descarga pero manteniendo al usuario en la página actual. La URL del navegador no cambia, y el usuario puede incluso hacer clic derecho en el enlace de descarga y usar Guardar destino como ... si lo desea.

+0

Definitivamente necesita la respuesta, pero mi pregunta es un poco más específica. El problema es que el código MS que trata con sus paneles de actualización "snafles" el archivo descargado. Fuera de un panel de actualización funciona como lo describes, pero no dentro. – philw

+0

@philw, ¿Has probado esta técnica tú mismo? Me funciona desde dentro de un UpdatePanel usando .NET 4.0. El UpdatePanel no debería importar nada en este caso porque no se está publicando en absoluto, sino más bien haciendo una solicitud GET normal, que no queda atrapada por el código AJAX de UpdatePanel. –

+0

El material de respuesta, por supuesto, necesita agregar también el contenido o no obtendrá ningún indicador de progreso. Creo (de memoria) ¡No puedo recordar cómo solucionamos el problema! – philw

3

Me doy cuenta de que esto fue preguntado hace un año, pero si ayuda a alguien más, la solución 2 funcionó para mí.

((ScriptManager)this.Page.Master.FindControl("scrptmgr")).RegisterPostBackControl(lnkbtn); 

La única manera que puedo conseguir que funcione es si el control (en este caso lnkbtn) es visible cuando la línea de código anterior se ejecuta.

Editar - Después de más pruebas, ahora parece que este método solo funciona si no hay devoluciones de datos entre registrar el control para hacer una devolución de datos completa y hacer clic en el objeto. La solución o hackeo es registrar el control para hacer una devolución de datos completa en cada carga de página.

+0

Interesante - He trabajado alrededor de otra manera (no puedo recordar cómo). La advertencia de "devolución de datos" puede ser la razón por la que esto no funcionó para mí. – philw

+0

Me salvó la noche. En mi caso, tenía mi propio evento que solo estaba vinculado al control principal que contenía el UpdatePanel. Mi código en OnInit de la página: anlagenSelector.SelectionChanged + = anlagenSelector_SelectionChanged; ((ScriptManager) this.Page.Master.FindControl ("scriptManager")). RegisterPostBackControl (anlagenSelector); – Tillito

0

En caso de que el control que debe obligar a la devolución de página a la página (suponga que un botón) es un campo de plantilla GridView, puede tener algunos problemas al configurar el control para el activador UpdatePanel ... en este caso puede simplemente ve al botón teemplatefield y establece su propiedad "PostBackUrl" en ... ¡la misma página!

De esta manera, haciendo clic en él, forzará una devolución de datos completa ...

Cuestiones relacionadas