Uso di TemplateFields nel controllo DetailsView (VB)
Le stesse funzionalità di TemplateFields disponibili con GridView sono disponibili anche con il controllo DetailsView. In questa esercitazione verrà visualizzato un prodotto alla volta usando DetailsView contenente TemplateFields.
Introduzione
TemplateField offre una maggiore flessibilità nel rendering dei dati rispetto a BoundField, CheckBoxField, HyperLinkField e altri controlli di campo dati. Nell'esercitazione precedente è stato esaminato l'uso di TemplateField in un oggetto GridView per:
- Visualizzare più valori di campo dati in una colonna. In particolare, entrambi i
FirstName
campi eLastName
sono stati combinati in una colonna GridView. - Usare un controllo Web alternativo per esprimere un valore di campo dati. È stato illustrato come visualizzare il
HiredDate
valore usando un controllo Calendario. - Visualizzare le informazioni sullo stato in base ai dati sottostanti. Sebbene la
Employees
tabella non contenga una colonna che restituisce il numero di giorni in cui è stato eseguito il processo, è stato possibile visualizzare tali informazioni nell'esempio di GridView nell'esercitazione precedente con l'uso di un metodo TemplateField e formattazione.
Le stesse funzionalità di TemplateFields disponibili con GridView sono disponibili anche con il controllo DetailsView. In questa esercitazione verrà visualizzato un prodotto alla volta usando DetailsView che contiene due Campi modello. Il primo ModelloField combina i UnitPrice
campi dati , UnitsInStock
e UnitsOnOrder
in una riga DetailsView. Il secondo TemplateField visualizzerà il valore del Discontinued
campo, ma userà un metodo di formattazione per visualizzare "SÌ" se Discontinued
è True
, e "NO" in caso contrario.
Figura 1: Vengono usati due campi modello per personalizzare la visualizzazione (fare clic per visualizzare l'immagine a dimensioni complete)
È possibile iniziare subito.
Passaggio 1: Associazione dei dati a DetailsView
Come illustrato nell'esercitazione precedente, quando si usa TemplateFields è spesso più semplice iniziare creando il controllo DetailsView che contiene solo BoundFields e quindi aggiungere nuovi Campi TemplateFields o convertirli in TemplateFields in TemplateFields in base alle esigenze. Per iniziare questa esercitazione, quindi, aggiungere un oggetto DetailsView alla pagina tramite il Designer e associarlo a un oggetto ObjectDataSource che restituisce l'elenco dei prodotti. Questi passaggi creeranno un oggetto DetailsView con BoundFields per ogni campo valore non booleano del prodotto e un campo CheckBoxField per il campo valore booleano (interrotto).
Aprire la DetailsViewTemplateField.aspx
pagina e trascinare detailsView dalla casella degli strumenti nella Designer. Dallo smart tag DetailsView scegliere di aggiungere un nuovo controllo ObjectDataSource che richiama il ProductsBLL
metodo della GetProducts()
classe.
Figura 2: Aggiungere un nuovo controllo ObjectDataSource che richiama il metodo (fare clic per visualizzare l'immagineGetProducts()
full-size)
Per questo report rimuovere , ProductID
SupplierID
, CategoryID
e ReorderLevel
BoundFields. Successivamente, riordinare i BoundFields in modo che i CategoryName
e SupplierName
BoundFields vengano visualizzati immediatamente dopo BoundField ProductName
. È possibile modificare le proprietà e le HeaderText
proprietà di formattazione per BoundFields come si vede. Come per GridView, queste modifiche a livello di BoundField possono essere eseguite tramite la finestra di dialogo Campi (accessibile facendo clic sul collegamento Modifica campi nello smart tag di DetailsView) o tramite la sintassi dichiarativa. Infine, deselezionare i valori delle proprietà e Width
di Height
DetailsView per consentire al controllo DetailsView di espandere in base ai dati visualizzati e selezionare la casella di controllo Abilita paging nello smart tag.
Dopo aver apportato queste modifiche, il markup dichiarativo del controllo DetailsView dovrebbe essere simile al seguente:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"
EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName" HeaderText="Supplier"
ReadOnly="True" SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice" HeaderText="Price"
SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock"
HeaderText="Units In Stock" SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder"
HeaderText="Units On Order" SortExpression="UnitsOnOrder" />
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
Prendere un momento per visualizzare la pagina tramite un browser. A questo punto si dovrebbe visualizzare un singolo prodotto elencato (Chai) con righe che mostrano il nome, la categoria, il fornitore, il prezzo, le unità in magazzino, le unità in ordine e il relativo stato interrotto.
Figura 3: i dettagli del prodotto vengono visualizzati usando una serie di campi delimitati (fare clic per visualizzare l'immagine full-size)
Passaggio 2: Combinare il prezzo, le unità in magazzino e le unità in ordine in una riga
DetailsView include una riga per i UnitPrice
campi , UnitsInStock
e UnitsOnOrder
. È possibile combinare questi campi dati in una singola riga con un ModelloField aggiungendo un nuovo TemplateField o convertendo uno degli elementi esistenti UnitPrice
, UnitsInStock
e UnitsOnOrder
BoundFields in un oggetto TemplateField. Mentre personalmente preferisco convertire BoundFields esistenti, è consigliabile aggiungere un nuovo TemplateField.
Iniziare facendo clic sul collegamento Modifica campi nello smart tag di DetailsView per visualizzare la finestra di dialogo Campi. Aggiungere quindi un nuovo TemplateField e impostarne HeaderText
la proprietà su "Price and Inventory" e spostare il nuovo TemplateField in modo che sia posizionato sopra boundfield UnitPrice
.
Figura 4: Aggiungere un nuovo modelloField al controllo DetailsView (Fare clic per visualizzare l'immagine full-size)
Poiché questo nuovo ModelloField conterrà i valori attualmente visualizzati in UnitPrice
, UnitsInStock
e UnitsOnOrder
BoundFields, verranno rimossi.
L'ultima attività per questo passaggio consiste nel definire il markup per price and Inventory TemplateField, che può essere eseguito tramite l'interfaccia ItemTemplate
di modifica dei modelli di DetailsView nell'Designer o tramite la sintassi dichiarativa del controllo. Come per GridView, è possibile accedere all'interfaccia di modifica dei modelli di DetailsView facendo clic sul collegamento Modifica modelli nello smart tag. Da qui è possibile selezionare il modello da modificare nell'elenco a discesa e quindi aggiungere eventuali controlli Web dalla casella degli strumenti.
Per questa esercitazione, iniziare aggiungendo un controllo Label all'oggetto Price and Inventory TemplateField.ItemTemplate
Fare quindi clic sul collegamento Modifica DataBindings dallo smart tag del controllo Web Etichetta e associare la Text
proprietà al UnitPrice
campo.
Figura 5: Associare la proprietà dell'etichetta Text
al UnitPrice
campo dati (fare clic per visualizzare l'immagine full-size)
Formattazione del prezzo come valuta
Con questa aggiunta, il controllo Web Label Web Price and Inventory TemplateField visualizzerà ora solo il prezzo per il prodotto selezionato. La figura 6 mostra una schermata dello stato di avanzamento finora quando viene visualizzata tramite un browser.
Figura 6: Il modello di prezzo e inventario Mostra il prezzo (fare clic per visualizzare l'immagine a dimensioni complete)
Si noti che il prezzo del prodotto non è formattato come valuta. Con un oggetto BoundField, la formattazione è possibile impostando la HtmlEncode
proprietà su False
e la DataFormatString
proprietà su {0:formatSpecifier}
. Per un modelloField, tuttavia, tutte le istruzioni di formattazione devono essere specificate nella sintassi di associazione dati o tramite l'uso di un metodo di formattazione definito all'interno del codice dell'applicazione, ad esempio nella classe code-behind della pagina di ASP.NET.
Per specificare la formattazione per la sintassi databinding usata nel controllo Web Etichetta, tornare alla finestra di dialogo DataBindings facendo clic sul collegamento Modifica dataBindings dallo smart tag dell'etichetta. È possibile digitare le istruzioni di formattazione direttamente nell'elenco a discesa Formato oppure selezionare una delle stringhe di formato definite. Analogamente alla proprietà BoundField DataFormatString
, la formattazione viene specificata usando {0:formatSpecifier}
.
Per il UnitPrice
campo usare la formattazione della valuta specificata selezionando il valore elenco a discesa appropriato o digitando in {0:C}
base alla mano.
Figura 7: Formattare il prezzo come valuta (fare clic per visualizzare l'immagine full-size)
Dichiarativamente, la specifica di formattazione è indicata come secondo parametro nei Bind
metodi o Eval
. Le impostazioni appena eseguite tramite il Designer comportano l'espressione databinding seguente nel markup dichiarativo:
<asp:Label ID="Label1" runat="server" Text='<%# Eval("UnitPrice", "{0:C}") %>'/>
Aggiunta dei campi dati rimanenti al modelloField
A questo punto è stato visualizzato e formattato il UnitPrice
campo dati in Price and Inventory TemplateField, ma è comunque necessario visualizzare i UnitsInStock
campi e UnitsOnOrder
. Verranno visualizzati in una riga sotto il prezzo e nelle parentesi. Dall'interfaccia di modifica del modello nella Designer, tale markup può essere aggiunto posizionando il cursore all'interno del modello e digitando semplicemente il testo da visualizzare. In alternativa, questo markup può essere immesso direttamente nella sintassi dichiarativa.
Aggiungere il markup statico, i controlli Web etichetta e la sintassi di associazione dei dati in modo che il modello di prezzo e inventario visualizzi le informazioni sul prezzo e sull'inventario, ad esempio:
UnitPrice
(In stock/On Order:UnitsInStock / UnitsOnOrder)
Dopo aver eseguito questa attività, il markup dichiarativo di DetailsView dovrebbe essere simile al seguente:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"
EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName"
HeaderText="Product" SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="Supplier" ReadOnly="True"
SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:TemplateField HeaderText="Price and Inventory">
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Eval("UnitPrice", "{0:C}") %>'></asp:Label>
<br />
<strong>
(In Stock / On Order: </strong>
<asp:Label ID="Label2" runat="server"
Text='<%# Eval("UnitsInStock") %>'></asp:Label>
<strong>/</strong>
<asp:Label ID="Label3" runat="server"
Text='<%# Eval("UnitsOnOrder") %>'>
</asp:Label><strong>)</strong>
</ItemTemplate>
</asp:TemplateField>
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
Con queste modifiche sono state consolidate le informazioni sul prezzo e sull'inventario in una singola riga DetailsView.
Figura 8: Le informazioni sul prezzo e sull'inventario vengono visualizzate in una singola riga (fare clic per visualizzare l'immagine a dimensioni complete)
Passaggio 3: Personalizzazione delle informazioni sul campo interrotte
La Products
colonna della Discontinued
tabella è un valore bit che indica se il prodotto è stato interrotto. Quando si associa un oggetto DetailsView (o GridView) a un controllo origine dati, i campi valore booleano, ad esempio , vengono implementati come CheckBoxFields mentre i campi valore non Boolean, ad ProductID
esempio Discontinued
, ProductName
e così via, vengono implementati come BoundFields. CheckBoxField esegue il rendering come casella di controllo disabilitata selezionata se il valore del campo dati è True e deselezionato in caso contrario.
Anziché visualizzare CheckBoxField, potrebbe essere necessario visualizzare il testo che indica se il prodotto è interrotto o meno. A questo scopo, è possibile rimuovere CheckBoxField da DetailsView e quindi aggiungere un Oggetto BoundField la cui DataField
proprietà è stata impostata su Discontinued
. Prendi un momento per farlo. Dopo questa modifica, DetailsView mostra il testo "True" per i prodotti interrotti e "False" per i prodotti ancora attivi.
Figura 9: Le stringhe true e false vengono usate per visualizzare lo stato interrotto (fare clic per visualizzare l'immagine full-size)
Si supponga di non voler usare le stringhe "True" o "False", ma "SÌ" e "NO", invece. Tale personalizzazione può essere eseguita con l'aiuto di un modelloField e un metodo di formattazione. Un metodo di formattazione può accettare in qualsiasi numero di parametri di input, ma deve restituire il codice HTML (come stringa) per inserire nel modello.
Aggiungere un metodo di formattazione alla DetailsViewTemplateField.aspx
classe code-behind della pagina denominata DisplayDiscontinuedAsYESorNO
che accetta un Northwind.ProductsRow
oggetto come parametro di input e restituisce una stringa. Come illustrato nell'esercitazione precedente, questo metodo deve essere contrassegnato come Protected
o Public
per essere accessibile dal modello.
Protected Function DisplayDiscontinuedAsYESorNO(discontinued As Boolean) As String
If discontinued Then
Return "YES"
Else
Return "NO"
End If
End Function
Questo metodo controlla il parametro di input (discontinued
) e restituisce "SÌ" se è True
, "NO" in caso contrario.
Nota
Nel metodo di formattazione esaminato nell'esercitazione precedente si ricorda che si passava in un campo dati che potrebbe contenere NULL
s e quindi necessario verificare se il valore della proprietà del dipendente aveva un valore di HiredDate
database NULL
prima di accedere alla EmployeesRow
proprietà del HiredDate
dipendente. Tale controllo non è necessario qui perché la Discontinued
colonna non può mai avere valori di database NULL
assegnati. Inoltre, questo è il motivo per cui il metodo può accettare un parametro di input booleano anziché dover accettare un'istanza ProductsRow
o un parametro di tipo Object
.
Con questo metodo di formattazione completo, tutto ciò che rimane consiste nel chiamarlo dall'oggetto TemplateField.ItemTemplate
Per creare TemplateField, rimuovere Discontinued
BoundField e aggiungere un nuovo TemplateField o convertire BoundField Discontinued
in un modellofield. Quindi, dalla visualizzazione markup dichiarativo modificare TemplateField in modo che contenga solo un ElementoTemplate che richiama il DisplayDiscontinuedAsYESorNO
metodo, passando il valore della proprietà dell'istanza Discontinued
correnteProductRow
. È possibile accedere tramite il Eval
metodo . In particolare, il markup di TemplateField dovrebbe essere simile al seguente:
<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
<ItemTemplate>
<%#DisplayDiscontinuedAsYESorNO(Convert.ToBoolean(Eval("Discontinued")))%>
</ItemTemplate>
</asp:TemplateField>
In questo modo il metodo verrà richiamato quando si esegue il DisplayDiscontinuedAsYESorNO
rendering di DetailsView, passando il ProductRow
valore dell'istanza Discontinued
. Poiché il Eval
metodo restituisce un valore di tipo Object
, ma il metodo prevede un parametro di input di tipo Boolean
, viene eseguito il DisplayDiscontinuedAsYESorNO
cast del valore restituito dai Eval
metodi in Boolean
. Il DisplayDiscontinuedAsYESorNO
metodo restituirà quindi "SÌ" o "NO" a seconda del valore ricevuto. Il valore restituito è quello visualizzato in questa riga DetailsView (vedere La figura 10).
Figura 10: I valori SÌ o NO sono ora visualizzati nella riga interrotta (fare clic per visualizzare l'immagine a dimensioni complete)
Riepilogo
Il ModelloField nel controllo DetailsView consente una maggiore flessibilità nella visualizzazione dei dati che sono disponibili con gli altri controlli di campo e sono ideali per situazioni in cui:
- È necessario visualizzare più campi dati in una colonna GridView
- I dati sono espressi in modo ottimale usando un controllo Web anziché testo normale
- L'output dipende dai dati sottostanti, ad esempio la visualizzazione dei metadati o la riformattazione dei dati
Anche se TemplateFields consente una maggiore flessibilità nel rendering dei dati sottostanti di DetailsView, l'output DetailsView sembra ancora un bit boxy perché ogni campo viene eseguito il rendering come riga in un codice HTML <table>
.
Il controllo FormView offre una maggiore flessibilità nella configurazione dell'output sottoposto a rendering. FormView non contiene campi ma solo una serie di modelli (ItemTemplate
, , EditItemTemplate
HeaderTemplate
e così via). Verrà illustrato come usare FormView per ottenere ancora più controllo del layout sottoposto a rendering nell'esercitazione successiva.
Programmazione felice!
Informazioni sull'autore
Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Microsoft Web dal 1998. Scott lavora come consulente indipendente, allenatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2,0 in 24 Ore. Può essere raggiunto a mitchell@4GuysFromRolla.com. o tramite il suo blog, che può essere trovato in http://ScottOnWriting.NET.
Grazie speciali
Questa serie di esercitazioni è stata esaminata da molti revisori utili. Il revisore principale per questa esercitazione è stato Dan Jagers. Interessati a esaminare i prossimi articoli MSDN? In tal caso, lasciami una riga in mitchell@4GuysFromRolla.com.
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: Nel corso del 2024 verranno gradualmente disattivati i problemi di GitHub come meccanismo di feedback per il contenuto e ciò verrà sostituito con un nuovo sistema di feedback. Per altre informazioni, vedereInvia e visualizza il feedback per