Uso di TemplateFields nel controllo DetailsView (VB)

di Scott Mitchell

Scarica il PDF

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 e LastName 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 UnitPricecampi dati , UnitsInStocke 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.

Vengono usati due campi modello per personalizzare la visualizzazione

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.

Aggiungere un nuovo controllo ObjectDataSource che richiama il metodo GetProducts()

Figura 2: Aggiungere un nuovo controllo ObjectDataSource che richiama il metodo (fare clic per visualizzare l'immagineGetProducts() full-size)

Per questo report rimuovere , ProductIDSupplierID, CategoryIDe 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.

I dettagli del prodotto vengono visualizzati usando una serie di BoundFields

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 UnitPricecampi , UnitsInStocke UnitsOnOrder . È possibile combinare questi campi dati in una singola riga con un ModelloField aggiungendo un nuovo TemplateField o convertendo uno degli elementi esistenti UnitPrice, UnitsInStocke 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 .

Aggiungere un nuovo modelloField al controllo DetailsView

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, UnitsInStocke 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.

Associare la proprietà Text dell'etichetta al campo dati UnitPrice

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.

Il modello di prezzo e inventario Mostra il prezzo

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.

Formattare il prezzo come valuta

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.

Le informazioni sul prezzo e sull'inventario vengono visualizzate in una singola riga

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 ProductIDesempio Discontinued, ProductNamee 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.

Le stringhe true e false vengono usate per visualizzare lo stato interrotto

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 EmployeesRowproprietà 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).

I valori SÌ o NO sono ora visualizzati nella riga interrotta

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, , EditItemTemplateHeaderTemplatee 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.