2010-05-04 12 views
33

Sfondo: Sto personalizzando un'applicazione ASP .NET/C# esistente. Ha il suo piccolo "framework" e le convenzioni che gli sviluppatori devono seguire quando estendono/personalizzano le sue funzionalità. Attualmente sto estendendo alcune delle sue funzionalità amministrative, alle quali il framework fornisce un contratto per imporre l'implementazione del metodo GetAdministrationInterface(), che restituisce System.Web.UI.Control. Questo metodo viene chiamato durante il metodo Page_Load() della pagina che ospita l'interfaccia della GUI.I gestori di eventi ASP .NET Button non vengono attivati ​​al primo clic, ma al secondo clic dopo una PostBack

Problema: Ho tre pulsanti nella GUI, a ognuno dei quali è stato assegnato un gestore di eventi. La mia interfaccia grafica di amministrazione si carica perfettamente, ma fare clic su uno dei pulsanti non fa ciò che mi aspetto che facciano. Tuttavia, quando li clicco una seconda volta, i pulsanti funzionano.

Ho inserito i punti di interruzione all'inizio di ogni metodo del gestore di eventi e ho eseguito il mio codice. Al primo clic, nessuno dei gestori di eventi è stato attivato. Al secondo clic, hanno sparato.

Qualche idea?

Esempio di Button Definizione (entro GetAdministrationInterface)

public override Control GetAdministrationInterface() 
{ 
    // more code... 

    Button btn = new Button(); 
    btn.Text = "Click Me!"; 
    btn.Click += new EventHandler(Btn_Click); 

    // more code... 
} 

Esempio di Event Handler Metodo Definizione

void Btn_Click(object sender, EventArgs e) 
{ 
    // Do Something 
} 

Page_Load metodo che chiama GetAdministrationInterface

protected void Page_Load(object sender, System.EventArgs e) 
{ 
    if (!Page.IsAsync) 
    { 
     List<AdministrationInterface> interfaces = <DATABASE CALL>; 
     foreach(AdministrationInteface ai in interfaces) 
     { 
      placeholderDiv.Controls.Add(ai.GetAdministrationInterface()); 
     } 
    } 
} 
+1

Dove si posiziona la vostra definizione pulsante e il gestore di eventi? Come vengono aggiunti i pulsanti alla pagina? –

+0

Pubblica il codice Page_Load che chiama 'GetAdminInterface' e crea i controlli –

+0

Ho aggiunto il codice' Page_Load' alla domanda originale. – John

risposta

62

Buona dolore! Sapevo che sarebbe stato qualcosa di così stupido. Puramente colpa mia, naturalmente, e della mia mancanza di conoscenza in ASP .NET.

Dopo aver eseguito una moltitudine di ricerche Google e infine bloccato da Google con l'accusa di essere un bot che esegue script automatici, sono riuscito a inserire un'ultima ricerca in e sono incappato in questo article. Già al punto di rinunciare, ho fatto del mio meglio per leggere l'articolo senza saltare 10 linee alla volta o cercare belle immagini. Nella sezione intitolata Assegnazione di ID per creati dinamicamente i controlli, ho letto queste parole magiche e più gioiosi:

Se si visualizza il sorgente HTML prima di fare clic sul pulsante non-lavoro e dopo aver cliccato, si noterà una piccola differenza. I pulsanti hanno ID HTML diversi prima e dopo il post-back. Ho ricevuto ctl04 e ctl05 prima del postback e ctl02 e ctl03 dopo il postback.

Il pulsante ASP.NET riconosce gli eventi controllando la presenza di un valore per il proprio ID nella raccolta Request.Form. (In realtà accade diversamente e i controlli non controllano la raccolta Request.Form da soli. La pagina passa i dati dei post ai controlli tramite i loro ID e ai controlli che sono registrati per essere notificati sui dati dei post). ASP.NET non attiva l'evento Click, poiché l'ID del pulsante è cambiato tra i postback. Il pulsante su cui hai fatto clic e il pulsante che vedi dopo sono pulsanti diversi per ASP.NET.

Abbastanza sicuro, quando ho visto l'HTML la prima volta, il mio pulsante aveva l'ID ctl04$ctl36. Dopo aver fatto clic sul pulsante, il mio pulsante aveva l'ID ctl04$ctl33.

Così ci sei! Tutto quello che dovevo fare era impostare l'ID sui pulsanti e presto! I miei gestori di eventi vengono ora chiamati!

Esempio Soluzione:

public override Control GetAdministrationInterface() 
{ 
    // more code... 

    Button btn = new Button(); 
    btn.Text = "Click Me!"; 
    // !!THE BANE OF MY EXISTENCE!! 
    btn.ID = "The_Bane_of_My_Existence"; 
    // !!THE BANE OF MY EXISTENCE!! 
    btn.Click += new EventHandler(Btn_Click); 

    // more code... 
} 

Che bel modo di trascorrere due giorni ...

+1

ben fatto e ben spiegato. Questa è la risposta al problema e tu mi hai salvato il bacon. –

+0

Ottimo lavoro, ho difficoltà a risolvere lo stesso problema negli ultimi 15 giorni. Ottimo articolo – Moons

+0

Fantastico !!! Questo post era esattamente quello che stavo cercando (per ore). Grazie! – SunfiShie

0

Mentre è difficile sapere esattamente senza visualizzare il metodo Page_load completo, ha un odore simile a quello che i gestori di eventi non stanno collegando fino a quando la pagina non viene ricaricata.

esempio:

if (IsPostBack) { 
    // Add handlers here ... 
} 
1

stavo affrontando lo stesso problema. Il mio pulsante si bloccò dopo il mio primo clic. Per me questo fastidioso problema è stato risolto quando ho disattivato l'attributo EnableViewState del pulsante.

15

Ho avuto lo stesso problema, ma la risposta accettata qui non lo stava causando. Ho avuto una casella di testo e un pulsante di ricerca, e facendo clic sul pulsante la prima volta non ha eseguito la ricerca. Il gestore di eventi del pulsante non veniva colpito. Ma facendo clic sul pulsante una seconda volta ha attivato l'evento sul server. Ecco perché:

Se si dispone di un <asp:Textbox> con la sua AutoPostBack insieme a true, dopo aver digitato la casella di testo e poi passare a fare clic su un pulsante, la casella di testo provoca un post-indietro immediatamente nel momento in cui perde la messa a fuoco. Quindi il clic anche del pulsante non viene conteggiato (la pagina è già stata posticipata in seguito all'evento della casella di testo). Ecco perché quando fai clic sul pulsante una seconda volta, funziona perché la casella di testo non è coinvolta nel secondo post-back.

Impostare la proprietà AutoPostBack di <asp:Textbox> su false per risolvere questo problema.

+0

Grazie! Ho controllato il mio codice e anche questo era il mio problema: ho dimenticato di rimuovere AutoPostBack = true property del markup di una text box nella pagina aspx. L'ho usato per eseguire il debug di un codice di convalida sul lato server invece di fare javascript sul lato client. Quando l'ho rimosso, viola, l'evento click si attiva ogni volta che faccio clic sul pulsante. Ora il metodo dell'evento click del pulsante può aggiornare la casella di testo. Pubblicare sulla risoluzione del tuo problema mi ha permesso di risparmiare ore di ricerche aggiuntive online per il problema. Grrr, odio ASP.NET, ma devo usarlo al lavoro. –

5

Una soluzione rapida è quella di impostare un ID per il controllo ASCX vostro stanno caricando su una pagina. Ad esempio, se il codice è simile a questo:

 UserControl SpecsControl = (UserControl)Page.LoadControl("../name.ascx"); 
     SpecsContainer.Controls.Add(SpecsControl); 

allora avete bisogno di aggiungere una riga (prima Controls.Add):

  SpecsControl.ID = "Aribtrary_Name"; 

Allora il vostro metodo del gestore è sparato al primo scatto.

0

Per me era il UpdatePanel, il mio Button e il mio TextBox erano entrambi all'interno di uno UpdatePanel, quindi quando ho post-back, ha causato alcuni comportamenti strani. Lo ha preso al di fuori dello UpdatePanel e questo lo ha risolto.

0

Anche io ho avuto lo stesso problema. la causa era "localhost: 1656/secure/login.aspx? ReturnUrl =% 2f". se la richiesta contiene % 2f come stringa di query, il primo post non sarà riuscito anche se "% 2f" sta rappresentando "/".

un modo per evitare questo avendo un controllo condizione in pageload

protected void Page_Load(object sender, EventArgs e) 
{ 
    string queryString = Request.QueryString.ToString(); 
    if(queryString == "ReturnUrl=%2f") 
    { 
     Response.Redirect("/secure/login.aspx"); 
    } 
} 
Problemi correlati