Come visto nell'articolo precedente, a partire da ASP.NET 2.0 è possibile impostare il DefaultButton ed il DefaultFocus di una pagina aspx, anche in presenza di MasterPage.
Il concetto e le problematiche di questo argomento si estendono anche in presenza di controlli genitori, primo fra tutti il controllo Login di ASP.NET, essendo infatti il bottone di Login interno al controllo (più precisamente nell'AnonymousTemplate), la stringa identificativa dell'ID del bottone "Accedi" viene modificata dal parser di ASP.NET al momento del rendering della pagina, creando di fatto un'eccezione durante la compilazione, poichè la proprietà DefaultButton si aspetta un ID di un controllo che erediti direttamente da IButtonControl, e non riconoscendolo genera l'eccezione.
Così come spiegato in presenza di MasterPage, anche per il controllo Login è possibile implementare più di una soluzione per far sì che il submit del login avvenga direttamente alla pressione del tasto Invio (Enter), andiamo a scoprire come fare.
Impostare il DefaultButton del controllo Login via codebehind
Per consentire il submit del controllo Login alla pressione del tasto Invio all'interno di una pagina aspx, per la quale sia stata definita anche una MasterPage, basta aggiungere questa riga di codice nel codebehind:
protected void Page_Init(object sender, EventArgs e)
{
Page.Form.DefaultButton = LoginView1.FindControl("LoginButton").UniqueID;
}
ancora una volta ci viene in aiuto il metodo FindControl presente ovviamente anche nel Login Control. Una volta recuperato il ButtonControl, ne assegniamo lo UniqueID alla proprietà DefaultButton della Pagina (si poteva specificare anche this, piuttosto che Page).
Questa tecnica funziona perfettamente anche se per la pagina aspx è stata specificata una MasterPage.
Desidero porre l'attenzione sul fatto che questa assegnazione sia stata specificata nell'evento Page_Init e non nel Page_Load, Init è il primo è vero evento durante l'inizializzazione della pagina, mentre il Load si verifica successivamente al caricamento della pagina richiesta. Qualcuno potrebbe obbiettare che inserire l'assegnazione del DefaultButton nell'evento Init potrebbe non far funzionare il submit alla pressione del tasto Invio, poichè il Login Control non è ancora caricato nella pagina. Questo è vero ma non costituisce un problema, le pagine aspx propagano i propri eventi anche ai server control in essa contenuti, sempre secondo la gerarchia di annidamento con cui sono definiti, quindi anche il Login Control verrà inizializzato così come avviene per la pagina che lo contiene. In conclusione, a livello di funzionamento è indifferente assegnare il DefaultButton nell'evento Init anzichè nel Load, ma credo sia più giusto inserirlo durante l'inizializzazione della pagina (e conseguentemente del controllo Login). Se qualcuno volesse aggiungere qualcosa in proposito, lo spazio dei commenti è a vostra disposizione.
Impostare il DefaultButton del controllo Login tramite il controllo Panel
Come più volte accennato, la pagina aspx è un container, all'interno del quale vengono definiti ASP.NET ed HTML control, alcuni di questi sono a loro volta dei contenitori di altri oggetti. Secondo questa logica è pertanto possibile definire più di un DefaultButton all'interno di una pagina aspx; ed è proprio basandosi su questo concetto che spiegheremo come settare un DefaultButton per un controllo Login che risulti attivo alla pressione del tasto Invio.
Possiamo definire il DefaultButton non solo per il Form del Page, ma anche per ogni singolo Panel presente nella pagina, ogni DefaultButton prevarrà sugli altri quando il Panel che lo contiene risulterà attivo (si starà operando al suo interno). Per il controllo Login basterà inserire un Panel Control subito dopo l' AnonymousTemplate. Il Login Control si troverà così dentro il Panel, per il quale specifichiamo il DefaultButton nell'omonima proprietà, in questo modo:
<asp:LoginView ID="LoginView1" runat="server">
<LoggedInTemplate>
<asp:LoginName ID="LoginName" runat="server" />
<asp:LoginStatus ID="LoginStatus" runat="server" />
</LoggedInTemplate>
<AnonymousTemplate>
<asp:Panel ID="panelLogin" runat="server" DefaultButton="Login$LoginButton">
<asp:Login ID="Login" runat="server" />
</asp:Panel>
</AnonymousTemplate>
</asp:LoginView>
non abbiamo fatto altro che specificare nella proprietà DefaultButton del Panel, la stringa identificativa del LoginButton, ed anche questo secondo metodo funziona bene in presenza di MasterPage, basta che il Panel risulti attivo, e siccome stiamo proprio operando all'interno del Panel quando scriviamo i nostri dati per il Login, alla pressione del tasto Invio, il Login Button scatenerà il submit.
Conclusioni
Il primo metodo è sicuramente da preferire, è più elegante e poi specifichiamo lo UniqueID, questo evita problematiche inerenti l'identificativo del controllo sia in caso che venga cambiata la stringa dell'ID nel markup della pagina, sia in presenza di uno o più annidamenti in controlli genitori. Ciò nonostante se abbiamo un solo Panel a livello di pagina anche il secondo metodo funziona bene, e la sua implementazione è davvero semplice ed immediata.
Per chi volesse approfondire il discorso sul DefaultButton (ed anche DefaultFocus), può leggere l'articolo precedente: Settare il DefaultButton in presenza di MasterPage.
Chiunque voglia aggiungere qualcosa o chiedere ulteriori chiarimenti su Impostare il DefaultButton in presenza del Controllo Login può farlo liberamente tramite i commenti, ogni vostro contributo alla discussione sarà ben accetto.