Utilizzo di FindControl: accesso ai controlli in Formview
-
05-07-2019 - |
Domanda
Sto sviluppando una semplice applicazione per la lista delle nozze, in cui gli ospiti possono prenotare il regalo che desiderano acquistare per gli sposi. La pagina Reserve racchiude alcuni campi all'interno di un paio di pannelli, tutti racchiusi in un FormView.
L'utente inserisce il nome, l'e-mail e la quantità di articoli che desidera prenotare e la pagina effettuerà le prenotazioni necessarie nel DB.
Il mio primo problema è stato che in FormView_ItemCommand non potevo fare riferimento a nessuno degli altri controlli in FormView .... Ho pensato che questo fosse un caso per FindControl, ma perché ho bisogno di un Formview quando ho mai avuto bisogno per ListViews o DetailViews?
In secondo luogo, so che il seguente codice funziona ...
Dim oCtrl as TextBox = Me.fvwReservation.FindControl("txtEmail")
Dim Test As String = oCtrl.Text
... ma perché non posso usare ...
Dim Test As String = Me.fvwReservation.FindControl("txtEmail").Text
??
Infine, non credo di averne bisogno in questa occasione, ma ho cercato varianti ricorsive di FindControl, ma in realtà non ne ho trovata una che lo compili! Qualche suggerimento?
È molto per un post - grazie in anticipo.
Snippet di codice gratuito:
<asp:FormView ID="fvwReservation" runat="Server" DataSourceID="dsGift">
<ItemTemplate>
<asp:Panel runat="server" ID="pnlDetails">
<h3>Reserve Item: <%#Eval("ShortDesc")%></h3>
<p>You have chosen to reserve the <em><%#Eval("LongDesc")%></em> gift.</p>
<p>Please enter your details below to confirm the reservation.</p>
</asp:Panel>
<asp:Panel runat="server" ID="pnlConfirm">
<div class="row">
<asp:Label runat="server" CssClass="label">Name:</asp:Label><asp:TextBox ID="txtName" MaxLength="50" runat="server" CssClass="Field" />
<asp:RequiredFieldValidator ID="rfvName" runat="server" ErrorMessage="You must specify your Name" ControlToValidate="txtName" />
</div>
<div class="row">
<asp:Label runat="server" CssClass="label">Email:</asp:Label><asp:TextBox ID="txtEmail" MaxLength="100" runat="server" CssClass="Field"/>
<asp:RequiredFieldValidator ID="rfvEmail" runat="server" ErrorMessage="You must specify your Email Address" ControlToValidate="txtEmail" />
<asp:RegularExpressionValidator ID="regexEmail" ValidationExpression="^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}<*>quot; runat="server" ErrorMessage="Please enter a valid Email Address" ControlToValidate="txtEmail" />
</div>
<div class="row">
<asp:Label runat="server" CssClass="label">Quantity (max <%#Eval("QtyRemaining")%>):</asp:Label><asp:TextBox ID="iQty" MaxLength="2" runat="server" CssClass="Field" />
<asp:RangeValidator ID="rvQty" runat="server" ErrorMessage="The Quantity mmust be between 1 and 10" MinimumValue="1" MaximumValue="10" ControlToValidate="iQty" />
</div>
<div class="row">
<asp:Label runat="server" CssClass="label"> </asp:Label>
<asp:Button ID="btnReserve" Text="Confirm Reservation" CommandName="Reserve" runat="server" />
</div>
</asp:Panel>
</ItemTemplate>
</asp:FormView>
Soluzione
Per la seconda domanda, FindControl restituisce un controllo generico e deve essere sottoposto al tipo specifico di controllo per ottenere l'accesso alle proprietà di quel tipo specifico di controllo.
Puoi farlo in una sola riga, in questo modo:
Dim Test As String = CType(Me.fvwReservation.FindControl("txtEmail"), TextBox).Text
Per quanto riguarda la tua prima domanda, mi piacerebbe conoscere anche la risposta.
Modifica
Ho esaminato alcune altre risposte StackOverflow (in particolare questo e questo ) . Poiché i controlli nel modello FormView non esistono finché il modello non è il modello attivo, non è possibile fare riferimento direttamente a essi nel codice sottostante. Pertanto, è necessario utilizzare FindControl durante un evento appropriato per accedere ai controlli.
Altri suggerimenti
Hmm, anche nei modelli FormView, non credo che FindControl funzionerà in modo affidabile, in genere lo userei solo con controlli di rendering HTML semplici, non quelli generati da ASP.net.
Sono abbastanza sicuro che i controlli basati su modelli dovrebbero essere disponibili nel codice lato Server (ad es. txtEmail.text) in caso contrario, ricontrolla il modello
Un FindControl ricorsivo è anche piuttosto faticoso sul Server e potenzialmente inaffidabile.
È necessario utilizzare il metodo ricorsivo FindControl per accedere agli elementi all'interno del controllo FormView. Esistono molte implementazioni disponibili e una è collegata di seguito:
http://www.highoncoding.com/Articles/606_Creating_a_BetterFontrControl