2011-10-31 8 views
6

Ho un GridView in un pannello di aggiornamento. È un asp ereditato: GridView, quindi ha una piccola icona "esportami" che fa proprio questo. Funziona rispondendo a un clic "esportazione" con un file XLS. Il problema è che se metti la GridView intelligente all'interno di un pannello di aggiornamento, ASP.NET pensa che il file XLS debba essere scritto nel pannello, che ovviamente non è quello che vogliamo. Per questo, ho bisogno di un post-back completo ogni volta.Forza postback completo a livello di programmazione da UpdatePanel

miei pannelli aggiornamento sono tutti programatically generati

soluzioni che non funzionano in questo preciso contesto (molti dei quali sono coperti altrove sul SO):

  1. In ASP.NET prima versione 4 , se hai lasciato l'ID su un controllo, farebbe un postback completo anche all'interno di un pannello di aggiornamento. La mia domanda è solo per il più recente e più grande. NET 4.

  2. ScriptManager.RegisterPostBackControl sembra promettente. Fa in modo che il controllo post-back utilizzi l'ID pannello corretto come eventtarget, ma non aiuta in altro modo.

  3. Aggiunta di un PostBackTrigger al pannello Aggiorna. I miei pannelli di aggiornamento sono generati a livello di codice e MS dichiara che questo non è supportato. I miei test indicano che hanno ragione: l'ho provato in ogni modo, ma questo non funziona.

  4. Non mi piace l'idea che GridView sia in grado di uscire da se stesso, ma ho cercato di mettere un controllo extra all'esterno di updatePanel in queste circostanze. L'idea di fare un clic sul lato client sul mio pulsante di esportazione all'interno del pannello deve essere reindirizzato dal client javascript per simulare un clic su quel pulsante al di fuori del pannello. Tuttavia, questo non funziona perché non posso aggiungere apparentemente il controllo "esterno" alla pagina - Ottengo il "La raccolta di controlli non può essere modificata durante le fasi DataBind, Init, Load, PreRender o Unload". errore.

  5. Utilizzare jQuery per spostare il controllo "Esporta" all'esterno del pannello. MS deve avere una lista di controlli che pensano siano "dentro" il pannello, e la posizione fisica all'interno del DOM non ha importanza.

Qualcuno ha qualche idea su come farlo funzionare? So molto di questo dovrebbe funzionare, ma non è esattamente la stessa cosa.

risposta

4

Per me la soluzione 3 funziona.

Aggiungo dinamicamente un UpdatePanel alla pagina, aggiungo uno Button al modello di contenuto e associo un PostBackTrigger. Ho aggiunto un gestore di eventi Click in cui aggiorno un'etichetta (al di fuori di UpdatePanel) con la data/ora corrente.

Vedere la configurazione di prova riportata di seguito.

Markup

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

Codice Dietro

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()); 
} 

Spero che questo aiuti.

+0

Non funziona in questo modo per me. Se aggiungo il "postBackTrigger" quando creo i pannelli, fallisce se il button.ID non è già presente (ragionevole), ma se lo aggiungo nel mio controllo personalizzato non ha alcun effetto - suggerisce qualche cosa del ciclo di vita . Ci penserò. – philw

+0

Se metto il controllo del pulsante nella pagina su OnInit() del controllo che contiene i pannelli di aggiornamento, funziona come suggerito. Se invece lo metto dove ne ho bisogno, nell'OnInit() del controllo personalizzato all'interno del pannello (cercando di eseguire il backup della gerarchia di controllo per trovare il pannello di aggiornamento), allora non funziona. Più sperimentazione .. – philw

+0

Non sono sicuro se ciò sarà di aiuto, ma esegui il checkout di questa domanda (in particolare la risposta): [FileUpload in FormView all'interno di un UpdatePanel] (http://stackoverflow.com/questions/3555917/fileupload-in-formview-inside -an-updatepanel) – jdavies

0

Ho creato un controllo GridView ereditato simile con la possibilità di esportare CSV. Il modo in cui l'ho gestito è di rendere il pulsante di esportazione un semplice <a href> alla pagina corrente con un parametro querystring appositamente predisposto "?SortablePagableGridViewExportToCSV=XXX" dove XXX è il UniqueID del mio controllo. Sovrascrivo il metodo Render del mio controllo, e lì controllo i parametri della richiesta manualmente per vedere se il parametro export è stato inviato. In tal caso, scrivo l'intestazione e la risposta del tipo di contenuto CSV come di seguito.

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 chiave è la chiamata alla Page.Response.End(), che interrompe ogni ulteriore elaborazione. Questa è una richiesta GET quindi non devo preoccuparmi dei postback asynch di UpdatePanel o di qualcosa del genere. Il browser si comporta magnificamente in questa situazione, facendo apparire il link di download ma mantenendo l'utente sulla pagina corrente. L'URL del browser non cambia e l'utente può anche fare clic con il pulsante destro del mouse sul link di download e utilizzare Salva oggetto con nome ... se lo desidera.

+0

Hai sicuramente bisogno della "risposta", ma la mia domanda è un po 'più specifica. Il problema è che il codice MS che si occupa dei loro pannelli di aggiornamento "filtra" il file scaricato. Fuori da un pannello di aggiornamento funziona come descrivi, ma non dentro. – philw

+0

@philw, hai provato questa tecnica da solo? Funziona per me all'interno di un UpdatePanel utilizzando .NET 4.0. In questo caso, UpdatePanel non dovrebbe avere alcuna importanza in quanto non sta affatto posticipando, ma piuttosto facendo una normale richiesta GET, che non viene intrappolata da alcun codice AJAX UpdatePanel. –

+0

Il materiale di risposta, ovviamente, è necessario aggiungere anche la lunghezza del contenuto o non si otterranno indicatori di progresso. Penso (dalla memoria) che non riesco a ricordare come abbiamo risolto il problema! – philw

3

Mi rendo conto che questo è stato chiesto un anno fa, ma se aiuta qualcun altro, la soluzione 2 ha funzionato per me.

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

L'unico modo in cui posso farlo funzionare è se il controllo (in questo caso lnkbtn) è visibile quando la linea di cui sopra di codice viene eseguito.

Modifica - Dopo ulteriori test ora sembra che questo metodo funziona solo se non ci sono postback tra la registrazione del controllo per fare un postback completo e in realtà cliccando la cosa. La soluzione o hack è di registrare il controllo per fare un postback completo su ogni caricamento della pagina.

+0

Interessante - Ci ho lavorato in un altro modo (non ricordo come). Il caveat "postbacks" potrebbe essere il motivo per cui questo non ha funzionato per me. – philw

+0

Salvato sera. Nel mio caso, ho avuto il mio evento che era legato solo al controllo principale che conteneva l'UpdatePanel. Il mio codice in OnInit della pagina: anlagenSelector.SelectionChanged + = anlagenSelector_SelectionChanged; ((ScriptManager) this.Page.Master.FindControl ("scriptManager")). RegisterPostBackControl (anlagenSelector); – Tillito

0

Nel caso in cui il controllo che dovrebbe forzare il postback della pagina (supponiamo un pulsante) sia --inside-- un campo di modello GridView, potresti avere alcuni problemi nell'impostare il controlId per il trigger UpdatePanel ... in questo caso puoi semplicemente vai al pulsante teemplatefield e imposta la proprietà "PostBackUrl" su ... stessa pagina!

In questo modo, facendo clic su di esso, verrà forzato un postback completo ...

Problemi correlati