Condividi tramite


Formattazione di DataList e Repeater in base ai dati (C#)

di Scott Mitchell

Scaricare il PDF

In questa esercitazione verranno illustrati esempi di formattazione dell'aspetto dei controlli DataList e Repeater, usando funzioni di formattazione all'interno dei modelli o gestendo l'evento DataBound.

Introduzione

Come illustrato nell'esercitazione precedente, DataList offre una serie di proprietà correlate allo stile che ne influiscono sull'aspetto. In particolare, è stato illustrato come assegnare classi CSS predefinite alle proprietà , HeaderStyleItemStyle, , e AlternatingItemStyle di DataListSelectedItemStyle. Oltre a queste quattro proprietà, DataList include una serie di altre proprietà correlate allo stile, ad esempio Font, ForeColorBackColor, e BorderWidth, per citarne alcune. Il controllo Repeater non contiene proprietà correlate allo stile. Tutte queste impostazioni di stile devono essere effettuate direttamente all'interno del markup nei modelli di Repeater.

Spesso, tuttavia, il modo in cui i dati devono essere formattati dipende dai dati stessi. Ad esempio, quando si elencano i prodotti, potrebbe essere necessario visualizzare le informazioni sul prodotto in un colore di carattere grigio chiaro se non è più disponibile oppure evidenziare il UnitsInStock valore se è zero. Come illustrato nelle esercitazioni precedenti, GridView, DetailsView e FormView offrono due modi distinti per formattare l'aspetto in base ai dati:

  • L'evento DataBound crea un gestore eventi per l'evento appropriatoDataBound, che viene generato dopo che i dati sono stati associati a ogni elemento (per GridView era l'eventoRowDataBound; per DataList e Repeater è l'eventoItemDataBound). Nel gestore di eventi, i dati appena vincolati possono essere esaminati e si possono prendere decisioni di formattazione. Questa tecnica è stata esaminata nell'esercitazione Formattazione personalizzata basata sui dati .
  • Formattazione di funzioni nei modelli quando si usano TemplateFields nei controlli DetailsView o GridView o un modello nel controllo FormView, è possibile aggiungere una funzione di formattazione alla classe code-behind della pagina ASP.NET, al livello di logica di business o a qualsiasi altra libreria di classi accessibile dall'applicazione Web. Questa funzione di formattazione può accettare un numero arbitrario di parametri di input, ma deve restituire il codice HTML per il rendering nel modello. Le funzioni di formattazione sono state esaminate per la prima volta nella prima esercitazione sull'uso dei TemplateFields nel controllo GridView.

Entrambe queste tecniche di formattazione sono disponibili con i controlli DataList e Repeater. In questa esercitazione verranno illustrati esempi che usano entrambe le tecniche per entrambi i controlli.

Utilizzo delItemDataBoundgestore eventi

Quando i dati sono associati a un DataList, da un controllo origine dati o tramite l'assegnazione di dati a livello di codice alla proprietà del DataSource controllo e la chiamata al relativo DataBind() metodo, viene generato l'evento DataList DataBinding, l'origine dati viene enumerata e ogni record di dati viene associato a DataList. Per ogni record nell'origine dati, DataList crea un DataListItem oggetto che viene quindi associato al record corrente. Durante questo processo, DataList genera due eventi:

  • ItemCreatedviene attivato dopo che il DataListItem è stato creato
  • ItemDataBound viene attivato dopo che il record corrente è stato associato al DataListItem

I passaggi seguenti descrivono il processo di data binding per il controllo DataList.

  1. L'evento DataBinding DataList viene generato

  2. I dati sono associati a DataList

    Per ogni record nell'origine dati

    1. Creare un oggetto DataListItem
    2. Attivare l'eventoItemCreated
    3. Collegare il record all'oggetto DataListItem
    4. Attivare l'eventoItemDataBound
    5. Aggiungere l'oggetto DataListItem alla Items raccolta

Quando si associano dati al controllo Repeater, viene eseguita la stessa sequenza di passaggi. L'unica differenza è che, anziché creare istanze di DataListItem, il Repeater utilizza RepeaterItem.

Annotazioni

Il lettore astuto potrebbe aver notato un'anomalia leggermente diversa tra la sequenza di passaggi che si verifica quando DataList e Repeater vengono associati ai dati rispetto a quando GridView viene associato ai dati. Alla fine del processo di data binding, GridView genera l'evento DataBound . Tuttavia, né il controllo DataList né Repeater hanno un evento di questo tipo. Ciò è dovuto al fatto che i controlli DataList e Repeater sono stati creati nuovamente nell'intervallo di tempo ASP.NET 1.x, prima che il modello del gestore eventi pre e post-livello fosse diventato comune.

Analogamente a GridView, un'opzione per la formattazione basata sui dati consiste nel creare un gestore eventi per l'evento ItemDataBound . Questo gestore eventi controlla i dati appena associati all'oggetto DataListItem o RepeaterItem e influisce sulla formattazione del controllo in base alle esigenze.

Per il controllo DataList, è possibile implementare le modifiche di formattazione per l'intero elemento usando le DataListItem proprietà correlate allo stile, che includono lo standard Font, ForeColor, BackColor, CssClasse così via. Per influire sulla formattazione di determinati controlli Web all'interno del modello di DataList, è necessario accedere e modificare lo stile di tali controlli Web a livello di codice. Abbiamo visto come svolgere questa operazione nel tutorial Formattazione personalizzata basata sui dati. Analogamente al controllo Repeater, la RepeaterItem classe non dispone di proprietà correlate allo stile. Pertanto, tutte le modifiche relative allo stile apportate a un RepeaterItem nel ItemDataBound gestore eventi devono essere eseguite a livello di codice accedendo e aggiornando i controlli Web all'interno del modello.

Poiché la ItemDataBound tecnica di formattazione per DataList e Repeater è praticamente identica, l'esempio si concentrerà sull'uso di DataList.

Passaggio 1: Visualizzazione delle informazioni sul prodotto nell'elenco dati

Prima di preoccuparsi della formattazione, creare prima di tutto una pagina che usa un oggetto DataList per visualizzare le informazioni sul prodotto. Nell'esercitazione precedente è stato creato un oggetto DataList il cui ItemTemplate nome, la categoria, il fornitore, la quantità per unità e il prezzo di ogni prodotto sono visualizzati. Facciamo di nuovo questa funzionalità in questo tutorial. A tale scopo, è possibile ricreare DataList e objectDataSource da zero oppure copiarli dalla pagina creata nell'esercitazione precedente (Basics.aspx) e incollarli nella pagina per questa esercitazione (Formatting.aspx).

Dopo aver replicato la funzionalità DataList e ObjectDataSource da Basics.aspx a Formatting.aspx, prenditi un attimo per modificare la proprietà del DataList da ID a un nome più descrittivo DataList1. Visualizzare quindi DataList in un browser. Come illustrato nella figura 1, l'unica differenza di formattazione tra ogni prodotto è che il colore di sfondo si alterna.

I prodotti sono elencati nel controllo DataList

Figura 1: I prodotti sono elencati nel controllo DataList (fare clic per visualizzare l'immagine a dimensione intera)

Per questa esercitazione, formattare DataList in modo che qualsiasi prodotto con un prezzo inferiore a $ 20,00 avrà sia il nome che il prezzo unitario evidenziato giallo.

Passaggio 2: Determinare il valore dei dati nel gestore eventi ItemDataBound a livello di codice

Poiché solo quei prodotti con un prezzo inferiore a $ 20,00 avranno la formattazione personalizzata applicata, dobbiamo essere in grado di determinare ogni prezzo del prodotto. Quando si associano dati a un oggetto DataList, DataList enumera i record nell'origine dati e, per ogni record, crea un'istanza di DataListItem, associando il record dell'origine dati a DataListItem. Dopo che i dati del record specifico sono stati associati all'oggetto correnteDataListItem, viene attivato l'evento del DataList.ItemDataBound È possibile creare un gestore eventi per questo evento per esaminare i valori dei dati per l'oggetto corrente DataListItem e, in base a tali valori, apportare eventuali modifiche di formattazione necessarie.

Creare un ItemDataBound evento per DataList e aggiungere il codice seguente:

protected void ItemDataBoundFormattingExample_ItemDataBound
    (object sender, DataListItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item ||
        e.Item.ItemType == ListItemType.AlternatingItem)
    {
        // Programmatically reference the ProductsRow instance bound
        // to this DataListItem
        Northwind.ProductsRow product =
            (Northwind.ProductsRow)((System.Data.DataRowView)e.Item.DataItem).Row;
        // See if the UnitPrice is not NULL and less than $20.00
        if (!product.IsUnitPriceNull() && product.UnitPrice < 20)
        {
            // TODO: Highlight the product's name and price
        }
    }
}

Anche se il concetto e la semantica dietro il gestore eventi di ItemDataBound DataList sono uguali a quelli usati dal gestore eventi di RowDataBound GridView nell'esercitazione Formattazione personalizzata basata su dati , la sintassi è leggermente diversa. Quando l'evento ItemDataBound viene generato, il DataListItem appena associato ai dati viene passato al gestore eventi corrispondente tramite e.Item (anziché e.Row, come avviene con il gestore dell'evento RowDataBound di GridView). Il gestore eventi di ItemDataBound DataList viene attivato per ogni riga aggiunta a DataList, incluse le righe di intestazione, le righe del piè di pagina e le righe separatrici. Tuttavia, le informazioni sul prodotto sono associate solo alle righe di dati. Pertanto, quando si usa l'evento ItemDataBound per esaminare i dati associati a DataList, è necessario prima assicurarsi di lavorare con un elemento di dati. A tale scopo, è possibile controllare la DataListItem proprietà sItemType, che può avere uno dei otto valori seguenti:

  • AlternatingItem
  • EditItem
  • Footer
  • Header
  • Item
  • Pager
  • SelectedItem
  • Separator

Sia Item che AlternatingItem``DataListItem costituiscono gli elementi dati di DataList. Supponendo che stiamo lavorando con un Item oppure AlternatingItem, si accede all'istanza effettiva ProductsRow collegata al DataListItem corrente. La DataListItem proprietà s DataItem contiene un riferimento all'oggetto DataRowView , la cui Row proprietà fornisce un riferimento all'oggetto effettivoProductsRow.

Successivamente, controlliamo la proprietà ProductsRow dell'istanza UnitPrice. Poiché il campo della tabella UnitPrice Products consente valori NULL, prima di tentare di accedere alla proprietà UnitPrice, è necessario verificare se ha un valore NULL usando il metodo IsUnitPriceNull(). Se il valore UnitPrice non è NULL, si verifica se è minore di $20,00. Se è effettivamente inferiore a $20,00, dobbiamo applicare la formattazione personalizzata.

Passaggio 3: Evidenziazione del nome e del prezzo del prodotto

Una volta che sappiamo che il prezzo di un prodotto è inferiore a $ 20,00, tutto ciò che rimane è quello di evidenziare il suo nome e prezzo. A tale scopo, è innanzitutto necessario fare riferimento a livello di codice ai controlli Label in ItemTemplate che visualizzano il nome e il prezzo del prodotto. Successivamente, è necessario che visualizzino uno sfondo giallo. Queste informazioni di formattazione possono essere applicate modificando direttamente le proprietà delle etichette BackColor (LabelID.BackColor = Color.Yellow); idealmente, però, tutte le questioni relative alla visualizzazione dovrebbero essere espresse tramite fogli di stile CSS. Infatti, è già disponibile un foglio di stile che fornisce la formattazione desiderata definita in Styles.css - AffordablePriceEmphasis, che è stata creata e discussa nell'esercitazione Formattazione personalizzata basata su dati .

Per applicare la formattazione, è sufficiente impostare le proprietà dei due controlli Etichetta Web su CssClass, come mostrato nel codice seguente.

// Highlight the product name and unit price Labels
// First, get a reference to the two Label Web controls
Label ProductNameLabel = (Label)e.Item.FindControl("ProductNameLabel");
Label UnitPriceLabel = (Label)e.Item.FindControl("UnitPriceLabel");
// Next, set their CssClass properties
if (ProductNameLabel != null)
    ProductNameLabel.CssClass = "AffordablePriceEmphasis";
if (UnitPriceLabel != null)
    UnitPriceLabel.CssClass = "AffordablePriceEmphasis";

Con il gestore eventi ItemDataBound completato, visita di nuovo la pagina Formatting.aspx in un browser. Come illustrato nella figura 2, questi prodotti con un prezzo inferiore a $ 20,00 hanno sia il nome che il prezzo evidenziati.

Tali prodotti meno di $ 20,00 sono evidenziati

Figura 2: Tali prodotti inferiori a $ 20,00 sono evidenziati (fare clic per visualizzare l'immagine a dimensione intera)

Annotazioni

Poiché il rendering di DataList viene eseguito come HTML <table>, le relative DataListItem istanze hanno proprietà correlate allo stile che possono essere impostate per applicare uno stile specifico all'intero elemento. Ad esempio, se si vuole evidenziare l'intero articolo giallo quando il prezzo era inferiore a $20,00, è possibile sostituire il codice che ha fatto riferimento alle etichette e impostare le relative CssClass proprietà con la riga di codice seguente: e.Item.CssClass = "AffordablePriceEmphasis" (vedere la figura 3).

Gli RepeaterItem oggetti che costituiscono il controllo Repeater, tuttavia, non offrono tali proprietà a livello di stile. Pertanto, l'applicazione di formattazione personalizzata al Repeater richiede l'applicazione di proprietà di stile ai controlli Web all'interno dei modelli di Repeater, proprio come nella figura 2.

L'intero prodotto è evidenziato per i prodotti inferiori a $20,00

Figura 3: L'intero articolo prodotto è evidenziato per i prodotti sotto $20,00 (fare clic per visualizzare l'immagine a dimensione intera)

Uso delle funzioni di formattazione dall'interno del modello

Nel tutorial Uso di TemplateFields nel controllo GridView abbiamo visto come utilizzare una funzione di formattazione all'interno di un TemplateField del GridView per applicare la formattazione personalizzata in base ai dati associati alle righe di GridView. Una funzione di formattazione è un metodo che può essere richiamato da un modello e restituisce il codice HTML da generare al suo posto. Le funzioni di formattazione possono risiedere nella classe code-behind della pagina ASP.NET oppure possono essere centralizzate in file di classe nella App_Code cartella o in un progetto di libreria di classi separato. Lo spostamento della funzione di formattazione dalla classe code-behind della pagina ASP.NET è ideale se si prevede di usare la stessa funzione di formattazione in più pagine ASP.NET o in altre applicazioni Web ASP.NET.

Per dimostrare le funzioni di formattazione, lasciare che le informazioni sul prodotto includano il testo [DISCONTINUED] accanto al nome del prodotto se è sospeso. Inoltre, evidenziamo il prezzo in giallo se è inferiore a $20,00 (come abbiamo fatto nell'esempio del ItemDataBound gestore eventi); se il prezzo è $20,00 o superiore, non visualizzare il prezzo reale, ma invece il testo, Si prega di chiamare per un preventivo. La figura 4 mostra una schermata dell'elenco di prodotti con queste regole di formattazione applicate.

Screenshot che mostra i prodotti elencati nel controllo DataList, con il prezzo dei prodotti che costano più di €20,00 sostituito con il testo

Figura 4: Per i prodotti costosi, il prezzo viene sostituito con il testo, Si prega di chiamare per un preventivo di prezzo (fare clic per visualizzare l'immagine a dimensione intera)

Passaggio 1: Creare le funzioni di formattazione

Per questo esempio sono necessarie due funzioni di formattazione, una che visualizza il nome del prodotto insieme al testo [DISCONTINUED], se necessario, e un'altra che visualizza un prezzo evidenziato se è minore di $20,00 o il testo, Si prega di chiamare per un preventivo di prezzo in caso contrario. È possibile creare queste funzioni nella classe code-behind della pagina ASP.NET e denominarle DisplayProductNameAndDiscontinuedStatus e DisplayPrice. Entrambi i metodi devono restituire il codice HTML per eseguire il rendering come stringa ed entrambi devono essere contrassegnati Protected (o Public) per poter essere richiamati dalla parte della sintassi dichiarativa della pagina ASP.NET. Il codice per questi due metodi segue:

protected string DisplayProductNameAndDiscontinuedStatus
    (string productName, bool discontinued)
{
    // Return just the productName if discontinued is false
    if (!discontinued)
        return productName;
    else
        // otherwise, return the productName appended with the text "[DISCONTINUED]"
        return string.Concat(productName, " [DISCONTINUED]");
}
protected string DisplayPrice(Northwind.ProductsRow product)
{
    // If price is less than $20.00, return the price, highlighted
    if (!product.IsUnitPriceNull() && product.UnitPrice < 20)
        return string.Concat("<span class=\"AffordablePriceEmphasis\">",
                              product.UnitPrice.ToString("C"), "</span>");
    else
        // Otherwise return the text, "Please call for a price quote"
        return "<span>Please call for a price quote</span>";
}

Si noti che il DisplayProductNameAndDiscontinuedStatus metodo accetta i valori dei productName campi dati e discontinued come valori scalari, mentre il metodo accetta un'istanza DisplayPriceProductsRow (anziché un unitPrice valore scalare). Entrambi gli approcci funzioneranno; tuttavia, se la funzione di formattazione lavora con valori scalari che possono contenere valori di database NULL (come UnitPrice; né ProductNameDiscontinued consentono valori NULL), è necessario prestare particolare attenzione nella gestione di questi input scalari.

In particolare, il parametro di input deve essere di tipo Object poiché il valore in ingresso potrebbe essere un'istanza DBNull anziché il tipo di dati previsto. Inoltre, è necessario effettuare un controllo per determinare se il valore in ingresso è un valore del database NULL . Ciò significa che, se si vuole che il DisplayPrice metodo accetti il prezzo come valore scalare, è necessario usare il codice seguente:

protected string DisplayPrice(object unitPrice)
{
    // If price is less than $20.00, return the price, highlighted
    if (!Convert.IsDBNull(unitPrice) && ((decimal) unitPrice) < 20)
        return string.Concat("<span class=\"AffordablePriceEmphasis\">",
                              ((decimal) unitPrice).ToString("C"), "</span>");
    else
        // Otherwise return the text, "Please call for a price quote"
        return "<span>Please call for a price quote</span>";
}

Si noti che il unitPrice parametro di input è di tipo Object e che l'istruzione condizionale è stata modificata per verificare se unitPrice è DBNull o meno. Inoltre, poiché il unitPrice parametro di input viene passato come Object, deve essere convertito a un valore decimale.

Passaggio 2: Chiamata della funzione di formattazione da ItemTemplate di DataList

Con le funzioni di formattazione aggiunte alla classe code-behind della pagina ASP.NET, tutto ciò che rimane consiste nell'richiamare queste funzioni di formattazione da DataList s ItemTemplate. Per chiamare una funzione di formattazione da un modello, inserire la chiamata di funzione all'interno della sintassi di associazione dati:

<%# MethodName(inputParameter1, inputParameter2, ...) %>

Nel ItemTemplate della DataList, il controllo Web ProductNameLabel Etichetta visualizza attualmente il nome del prodotto assegnando alla sua proprietà Text il risultato di <%# Eval("ProductName") %>. Per visualizzare il nome più il testo [DISCONTINUED], se necessario, aggiornare la sintassi dichiarativa in modo che assegni alla proprietà Text il valore del metodo DisplayProductNameAndDiscontinuedStatus. In questo caso, è necessario passare il nome del prodotto e i valori di interruzione usando la sintassi Eval("columnName"). Eval restituisce un valore di tipo Object, ma il DisplayProductNameAndDiscontinuedStatus metodo prevede parametri di input di tipo String e Boolean, pertanto è necessario eseguire il cast dei valori restituiti dal Eval metodo ai tipi di parametro di input previsti, come in questo modo:

<h4>
    <asp:Label ID="ProductNameLabel" runat="server"
        Text='<%# DisplayProductNameAndDiscontinuedStatus((string) Eval("ProductName"),
              (bool) Eval("Discontinued")) %>'>
    </asp:Label>
</h4>

Per visualizzare il prezzo, è sufficiente impostare la UnitPriceLabel proprietà Label s Text sul valore restituito dal DisplayPrice metodo , proprio come è stato fatto per visualizzare il nome del prodotto e il testo [DISCONTINUED]. Tuttavia, invece di passare il UnitPrice come parametro di input scalare, si passa l'intera istanza ProductsRow.

<asp:Label ID="UnitPriceLabel" runat="server"
    Text='<%# DisplayPrice((Northwind.ProductsRow)
          ((System.Data.DataRowView) Container.DataItem).Row) %>'>
</asp:Label>

Con le chiamate alle funzioni di formattazione in atto, prenditi un momento per visualizzare il nostro progresso in un browser. La schermata dovrebbe essere simile alla figura 5, con i prodotti non più disponibili, incluso il testo [DISCONTINUED] e i prodotti che costano più di $ 20,00 hanno il loro prezzo sostituito con il testo Si prega di chiamare per un preventivo di prezzo .

Screenshot che mostra i prodotti elencati nel controllo DataList, con il prezzo dei prodotti che costano più di $ 20,00 sostituiti con il testo 'Si prega di chiamare per un preventivo' e il testo '[FUORI PRODUZIONE]' aggiunto al nome dei prodotti a fine vita.

Figura 5: Per i prodotti costosi, il prezzo viene sostituito con il testo, Si prega di chiamare per un preventivo di prezzo (fare clic per visualizzare l'immagine a dimensione intera)

Riassunto

La formattazione del contenuto di un controllo DataList o Repeater in base ai dati può essere eseguita usando due tecniche. La prima tecnica consiste nel creare un gestore eventi per l'evento ItemDataBound, che viene attivato mentre ogni record nell'origine dati è associato a un nuovo oggetto DataListItem o RepeaterItem. ItemDataBound Nel gestore eventi è possibile esaminare i dati dell'elemento corrente e quindi applicare la formattazione al contenuto del modello o, per DataListItem s, all'intero elemento stesso.

In alternativa, la formattazione personalizzata può essere realizzata tramite funzioni di formattazione. Una funzione di formattazione è un metodo che può essere richiamato dai modelli di DataList o Repeater che restituisce il codice HTML da generare al suo posto. Spesso, il codice HTML restituito da una funzione di formattazione è determinato dai valori associati all'elemento corrente. Questi valori possono essere passati alla funzione di formattazione, come valori scalari o passando l'intero oggetto associato all'elemento, ad esempio l'istanza ProductsRow .

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 molti revisori competenti. I revisori principali per questa esercitazione erano Yaakov Ellis, Randy Schmidt e Liz Shulok. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, mandami un messaggio a mitchell@4GuysFromRolla.com.