Uso di TemplateFields nel controllo DetailsView (VB)
Le stesse funzionalità TemplateFields disponibili con GridView sono disponibili anche con il controllo DetailsView. In questa esercitazione verrà visualizzato un prodotto alla volta usando un controllo DetailsView contenente TemplateFields.
Introduzione
TemplateField offre un livello di flessibilità superiore per il rendering dei dati rispetto a BoundField, CheckBoxField, HyperLinkField e altri controlli dei campi dati. Nell'esercitazione precedente è stato esaminato l'uso di TemplateField in un controllo 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. - Mostra informazioni sullo stato in base ai dati sottostanti. Anche se la
Employees
tabella non contiene una colonna che restituisce il numero di giorni in cui un dipendente è stato sul processo, è stato possibile visualizzare tali informazioni nell'esempio gridView dell'esercitazione precedente con l'uso di un metodo TemplateField e formattazione.
Le stesse funzionalità TemplateFields disponibili con GridView sono disponibili anche con il controllo DetailsView. In questa esercitazione verrà visualizzato un prodotto alla volta usando un controllo DetailsView che contiene due Campi Modello. Il primo oggetto TemplateField 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 "YES" 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 dimensione intera)
È ora di iniziare.
Passaggio 1: Associazione dei dati a DetailsView
Come illustrato nell'esercitazione precedente, quando si lavora con TemplateFields, è spesso più semplice iniziare creando il controllo DetailsView che contiene solo BoundFields e quindi aggiungere nuovi Campi TemplateFields o convertire i Campi BoundField esistenti in TemplateFields in Base alle esigenze. Pertanto, iniziare questa esercitazione aggiungendo un controllo DetailsView alla pagina tramite la finestra di progettazione e associandolo a un ObjectDataSource che restituisce l'elenco dei prodotti. Questi passaggi creeranno un controllo DetailsView con BoundFields per ognuno dei campi valore non booleani del prodotto e un campo CheckBoxField per il campo valore booleano (sospeso).
Aprire la DetailsViewTemplateField.aspx
pagina e trascinare detailsView dalla casella degli strumenti nella finestra di progettazione. 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'immagine GetProducts()
a dimensione intera)
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 HeaderText
proprietà e le proprietà di formattazione per BoundFields nel modo desiderato. 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 DetailsView) o tramite la sintassi dichiarativa. Infine, deselezionare i valori delle proprietà e Width
di Height
DetailsView per consentire al controllo DetailsView di espandersi 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>
Dedicare qualche istante alla visualizzazione della pagina tramite un browser. A questo punto dovrebbe essere visualizzato 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 di interruzione.
Figura 3: I dettagli del prodotto vengono visualizzati usando una serie di campi delimitati (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 2: Combinazione del prezzo, delle unità in magazzino e delle 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 oggetto TemplateField aggiungendo un nuovo oggetto TemplateField o convertendo uno dei campi dati esistenti UnitPrice
, UnitsInStock
e UnitsOnOrder
BoundFields in un oggetto TemplateField. Mentre personalmente preferisco convertire i BoundField esistenti, è consigliabile aggiungere un nuovo TemplateField.
Per iniziare, fare clic sul collegamento Modifica campi nello smart tag DetailsView per visualizzare la finestra di dialogo Campi. Aggiungere quindi un nuovo TemplateField e impostarne la HeaderText
proprietà su "Price and Inventory" e spostare il nuovo TemplateField in modo che sia posizionato sopra BoundField UnitPrice
.
Figura 4: Aggiungere un nuovo campo modello al controllo DetailsView (fare clic per visualizzare l'immagine a dimensione intera)
Poiché questo nuovo TemplateField conterrà i valori attualmente visualizzati in UnitPrice
, UnitsInStock
e UnitsOnOrder
BoundFields, verranno rimossi.
L'ultima attività per questo passaggio consiste nel definire il ItemTemplate
markup per Price and Inventory TemplateField, che può essere eseguito tramite l'interfaccia di modifica del modello di DetailsView in Progettazione o tramite la sintassi dichiarativa del controllo. Come per GridView, è possibile accedere all'interfaccia di modifica del modello di DetailsView facendo clic sul collegamento Modifica modelli nello smart tag. Da qui è possibile selezionare il modello da modificare dall'elenco a discesa e quindi aggiungere eventuali controlli Web dalla casella degli strumenti.
Per questa esercitazione, iniziare aggiungendo un controllo Label all'oggetto ItemTemplate
TemplateField di Price and Inventory TemplateField. 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 a dimensione intera)
Formattazione del prezzo come valuta
Con questa aggiunta, il controllo Web Label Price and Inventory TemplateField visualizzerà ora solo il prezzo per il prodotto selezionato. La figura 6 mostra una schermata dello stato di avanzamento finora visualizzato tramite un browser.
Figura 6: Il campo Modello prezzo e inventario Mostra il prezzo (fare clic per visualizzare l'immagine a dimensione intera)
Si noti che il prezzo del prodotto non è formattato come valuta. Con boundfield, la formattazione è possibile impostando la HtmlEncode
proprietà su False
e la DataFormatString
proprietà su {0:formatSpecifier}
. Per un oggetto TemplateField, tuttavia, qualsiasi istruzione di formattazione deve essere specificata nella sintassi di associazione dati o tramite l'uso di un metodo di formattazione definito in un punto qualsiasi all'interno del codice dell'applicazione, ad esempio nella classe code-behind della pagina ASP.NET.
Per specificare la formattazione per la sintassi di associazione dati utilizzata 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 o selezionare una delle stringhe di formato definite. Analogamente alla proprietà BoundField DataFormatString
, la formattazione viene specificata tramite {0:formatSpecifier}
.
Per il UnitPrice
campo usare la formattazione della valuta specificata selezionando il valore dell'elenco a discesa appropriato o digitando {0:C}
a mano.
Figura 7: Formattare il prezzo come valuta (fare clic per visualizzare l'immagine a dimensione intera)
In modo dichiarativo, la specifica di formattazione è indicata come secondo parametro nei Bind
metodi o Eval
. Le impostazioni eseguite tramite progettazione comportano l'associazione dati seguente nell'espressione di associazione dati nel markup dichiarativo:
<asp:Label ID="Label1" runat="server" Text='<%# Eval("UnitPrice", "{0:C}") %>'/>
Aggiunta dei campi dati rimanenti a TemplateField
A questo punto è stato visualizzato e formattato il UnitPrice
campo dati nel campo Modello prezzo e inventario, ma è comunque necessario visualizzare i UnitsInStock
campi e UnitsOnOrder
. Verranno ora visualizzati su una riga sotto il prezzo e tra parentesi. Dall'interfaccia di modifica del modello in Progettazione, 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 label e la sintassi di associazione dati in modo che il campo Modello di prezzo e inventario visualizzi le informazioni relative al prezzo e all'inventario, come indicato di seguito:
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 è stato consolidato il prezzo e le informazioni di inventario in una singola riga DetailsView.
Figura 8: Le informazioni sul prezzo e l'inventario vengono visualizzate in una singola riga (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 3: Personalizzazione delle informazioni sul campo sospese
La Products
colonna della Discontinued
tabella è un valore di bit che indica se il prodotto è stato sospeso. Quando si associa un controllo DetailsView (o GridView) a un controllo origine dati, i campi valore booleano, ad esempio Discontinued
, vengono implementati come Campi CheckBox, mentre i campi di valore non booleani, ad esempio ProductID
, ProductName
e così via, vengono implementati come BoundFields. Il controllo CheckBoxField viene eseguito come casella di controllo disabilitata selezionata se il valore del campo dati è True e deselezionato in caso contrario.
Anziché visualizzare checkBoxField, è consigliabile visualizzare il testo che indica se il prodotto non è più disponibile. A tale scopo, è possibile rimuovere CheckBoxField da DetailsView e quindi aggiungere un BoundField la cui DataField
proprietà è stata impostata su Discontinued
. Fai un po' di tempo per farlo. Dopo questa modifica, DetailsView mostra il testo "True" per i prodotti non più attivi e "False" per i prodotti ancora attivi.
Figura 9: Le stringhe True e False vengono usate per visualizzare lo stato sospeso (fare clic per visualizzare l'immagine a dimensione intera)
Si supponga di non voler usare le stringhe "True" o "False", ma "YES" e "NO". Tale personalizzazione può essere eseguita con l'aiuto di un TemplateField e di un metodo di formattazione. Un metodo di formattazione può accettare un numero qualsiasi 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 "YES" se è True
, "NO" in caso contrario.
Nota
Nel metodo di formattazione esaminato nell'esercitazione precedente si ricorda che è stato passato un campo dati che potrebbe contenere NULL
s e pertanto necessario per verificare se il valore della proprietà del dipendente ha un valore di HiredDate
database NULL
prima di accedere alla EmployeesRow
proprietà del HiredDate
dipendente. Questo controllo non è necessario 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
.
Al termine di questo metodo di formattazione, tutto ciò che rimane consiste nel chiamarlo da TemplateField.With this formatting method complete, all that that remains is to call it from the TemplateField's ItemTemplate
. Per creare TemplateField, rimuovere BoundField Discontinued
e aggiungere un nuovo Oggetto TemplateField o convertire BoundField Discontinued
in un oggetto TemplateField. Quindi, dalla visualizzazione di markup dichiarativo, modificare TemplateField in modo che contenga solo un ItemTemplate che richiama il DisplayDiscontinuedAsYESorNO
metodo, passando il valore della proprietà dell'istanza Discontinued
correnteProductRow
. È possibile accedervi 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 DisplayDiscontinuedAsYESorNO
metodo verrà richiamato durante il rendering di DetailsView, passando il ProductRow
valore dell'istanza Discontinued
. Poiché il Eval
metodo restituisce un valore di tipo Object
, ma il DisplayDiscontinuedAsYESorNO
metodo prevede un parametro di input di tipo Boolean
, il cast dei metodi restituisce il Eval
valore a Boolean
. Il DisplayDiscontinuedAsYESorNO
metodo restituirà quindi "YES" 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 sospesa (fare clic per visualizzare l'immagine a dimensione intera)
Riepilogo
Il campo Template nel controllo DetailsView consente un livello di flessibilità superiore nella visualizzazione dei dati rispetto a quello disponibile con gli altri controlli 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 di metadati o la riformattazione dei dati
Sebbene TemplateFields consenta una maggiore flessibilità nel rendering dei dati sottostanti di DetailsView, l'output DetailsView rimane un po' boxy perché ogni campo viene sottoposto a 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 un maggiore controllo del layout di cui è stato eseguito il rendering nell'esercitazione successiva.
Buon programmatori!
Informazioni sull'autore
Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Web Microsoft dal 1998. Scott lavora come consulente indipendente, formatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2.0 in 24 ore. Può essere raggiunto all'indirizzo mitchell@4GuysFromRolla.com. o tramite il suo blog, che può essere trovato all'indirizzo http://ScottOnWriting.NET.
Grazie speciale a
Questa serie di esercitazioni è stata esaminata da molti revisori utili. Il revisore principale per questa esercitazione era Dan Jagers. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, rilasciarmi una riga in mitchell@4GuysFromRolla.com.