Condividi tramite


Uso di TemplateFields nel controllo DetailsView (VB)

di Scott Mitchell

Scarica PDF

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. Nella esercitazione precedente abbiamo 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 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.
  • 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 in servizio, siamo riusciti a visualizzare tali informazioni nell'esempio GridView dell'esercitazione precedente con l'uso di un TemplateField e di un metodo di 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 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 "YES" se Discontinued è True, e "NO" in caso contrario.

Due campi modello vengono usati per personalizzare lo schermo

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 DetailsView con BoundFields per ogni campo valore non booleano del prodotto e un CheckBoxField per il campo valore booleano (interrotto).

Aprire la DetailsViewTemplateField.aspx pagina e trascinare DetailsView dalla Casella degli strumenti nel 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'immagine GetProducts()a dimensione intera)

Per il 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, cancellare i valori delle proprietà Height e Width di DetailsView per consentire al controllo DetailsView di espandersi in base ai dati visualizzati e selezionare la casella di controllo Abilita paging nel tag intelligente.

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.

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 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 campi UnitPrice, 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, UnitsInStocke UnitsOnOrder BoundFields in un oggetto TemplateField. Mentre personalmente preferisco convertire i BoundField esistenti, esercitiamoci aggiungendo 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 .

Aggiungere un nuovo campo modello al controllo DetailsView

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, UnitsInStocke 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, inizia aggiungendo un controllo Label al ItemTemplateTemplateField di Price e Inventory. Fare quindi clic sul collegamento "Modifica DataBindings" dallo smart tag del controllo Web Etichetta e associare il campo UnitPrice alla proprietà Text.

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 a dimensione intera)

Formattare il prezzo in 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.

Il campo Modello prezzo e inventario mostra il prezzo

Figura 6: Il campo Modello prezzo e inventario mostra il prezzo (fare clic per visualizzare l'immagine a grandezza naturale)

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 Label, tornare alla finestra di dialogo DataBindings facendo clic sul collegamento Modifica DataBindings dallo smart tag del controllo Label. È 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.

Formattare il prezzo come una valuta

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 metodi Bind o Eval. Le impostazioni appena effettuate tramite il Designer comportano la seguente espressione di associazione dati nel markup dichiarativo:

<asp:Label ID="Label1" runat="server" Text='<%# Eval("UnitPrice", "{0:C}") %>'/>

Aggiunta dei campi dati rimanenti al "TemplateField"

A questo punto abbiamo visualizzato e formattato il campo dati UnitPrice nel TemplateField di Prezzo e Inventario, ma dobbiamo ancora visualizzare i campi UnitsInStock 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:

Prezzo unitario
(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.

Le informazioni relative al prezzo e all'inventario vengono visualizzate in una singola riga

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, ProductNamee così via, vengono implementati come BoundFields. Il controllo CheckBoxField viene reso come una casella di controllo disabilitata che è segnata se il valore del campo dati è True e non selezionata 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.

Le stringhe True e False vengono utilizzate per visualizzare lo stato sospeso

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, ricorda che stavamo passando un campo dati che potrebbe contenere NULL s ed era quindi necessario verificare se il valore della proprietà del dipendente ha un valore NULL del database HiredDate prima di accedere alla proprietà EmployeesRow 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 il TemplateField affinché contenga soltanto un ItemTemplate che richiama il metodo DisplayDiscontinuedAsYESorNO, passando come valore la proprietà dell'istanza ProductRow corrente Discontinued. È 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>

Quando viene eseguito il rendering di DetailsView, questo causerà l'invocazione del metodo DisplayDiscontinuedAsYESorNO, passando il valore Discontinued dell'istanza ProductRow. 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).

I valori YES o NO sono ora visualizzati nella riga sospesa

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 i TemplateFields consentano una maggiore flessibilità nel rendering dei dati sottostanti di DetailsView, l'output di DetailsView appare ancora un po' ingombrante perché ogni campo viene reso come una riga in un elemento 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, HeaderTemplatee così via). Vedremo come usare FormView per ottenere un maggiore controllo del layout renderizzato nel nostro prossimo tutorial.

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 a mitchell@4GuysFromRolla.com.

Grazie speciale a

Questa serie di esercitazioni è stata esaminata da diversi revisori validi. Il revisore principale per questo tutorial è stato Dan Jagers. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, mandami un messaggio a mitchell@4GuysFromRolla.com.