Condividi tramite


Uso di TemplateFields nel controllo DetailsView (C#)

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

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 questo report rimuovere ProductID, SupplierID, CategoryIDe 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.

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

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, iniziare aggiungendo un controllo Label all'oggetto ItemTemplateTemplateField 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.

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)

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.

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

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

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

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 valore Boolean 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 string DisplayDiscontinuedAsYESorNO(bool discontinued)
{
    if (discontinued)
        return "YES";
    else
        return "NO";
}

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 EmployeesRowproprietà 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((bool)
          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 bool, il cast dei metodi restituisce il Eval valore a bool. 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 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, HeaderTemplatee 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.