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

di Scott Mitchell

Scarica il PDF

In questa esercitazione verranno illustrati alcuni esempi di come formattare l'aspetto dei controlli DataList e Repeater, usando le 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à , ItemStyle, AlternatingItemStylee SelectedItemStyle di HeaderStyleDataList. Oltre a queste quattro proprietà, DataList include una serie di altre proprietà correlate allo stile, ad esempio Font, ForeColor, BackColore 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 o si potrebbe voler 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 è l'eventoRowDataBound; per DataList e Repeater è l'eventoItemDataBound). In tale gestore eventi, i dati appena associati possono essere esaminati e prendere decisioni di formattazione. Questa tecnica è stata esaminata nell'esercitazione Formattazione personalizzata basata sui dati .
  • Funzioni di formattazione 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 della 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 nell'esercitazione Uso di TemplateFields nell'esercitazione 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.

Uso delItemDataBoundgestore eventi

Quando i dati sono associati a un oggetto 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 enumerata e ogni record di dati è 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 generato dopo la creazione dell'oggetto DataListItem
  • ItemDataBound viene generato dopo che il record corrente è stato associato al DataListItem

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

  1. Viene generato l'evento diDataBinding DataList

  2. I dati sono associati a DataList

    Per ogni record nell'origine dati

    1. Creare un DataListItem oggetto
    2. Generare l'eventoItemCreated
    3. Associare il record all'oggetto DataListItem
    4. Generare l'eventoItemDataBound
    5. Aggiungere l'oggetto DataListItemItems alla raccolta

Quando si associano dati al controllo Repeater, viene eseguita la stessa sequenza di passaggi. L'unica differenza è che, anziché le DataListItem istanze create, il Repeater usa RepeaterItems.

Nota

Il lettore astuto potrebbe aver notato un'anomalia leggermente tra la sequenza di passaggi traspire quando DataList e Repeater sono associati ai dati rispetto a quando GridView è 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 di nuovo nell'intervallo di tempo ASP.NET 1.x, prima che il modello di 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 a 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 a livello di codice e modificare lo stile di tali controlli Web. È stato illustrato come eseguire questa operazione nell'esercitazione Formattazione personalizzata basata sui dati . Analogamente al controllo Repeater, la RepeaterItem classe non dispone di proprietà correlate allo stile. Pertanto, tutte le modifiche correlate 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 in DataList

Prima di preoccuparsi della formattazione, creare prima 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, categoria, fornitore, quantità per unità e prezzo vengono visualizzati ogni prodotto. Ripetere questa funzionalità qui in questa esercitazione. A tale scopo, è possibile ricreare DataList e objectDataSource da zero oppure copiare tali controlli 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 in , modificare la proprietà DataList1 di DataList da ID a un oggetto più descrittivoItemDataBoundFormattingExampleFormatting.aspx. Visualizzare quindi l'oggetto 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 il prezzo di ogni prodotto. Quando si associano dati a un oggetto DataList, DataList enumera i record nell'origine dati e, per ogni record, crea un'istanza DataListItem , associando il record dell'origine DataListItemdati a . Dopo che i dati del record specifico sono stati associati all'oggetto correnteDataListItem, viene generato l'evento di 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 le 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 alla base del gestore eventi di DataList sono ItemDataBound gli stessi usati dal gestore eventi di RowDataBound GridView nell'esercitazione Formattazione personalizzata basata su dati , la sintassi è leggermente diversa. Quando l'evento viene generato, l'oggetto ItemDataBoundDataListItem appena associato ai dati viene passato al gestore eventi corrispondente tramite e.Item (invece di e.Row, come con il gestore eventi di RowDataBound GridView). Il gestore eventi di DataList viene ItemDataBound generato per ogni riga aggiunta a DataList, incluse le righe di intestazione, le righe del piè di pagina e le righe separatori. 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, controllare la DataListItem proprietà sItemType, che può avere uno dei seguenti otto valori:

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

AlternatingItem``DataListItem Sia che Item trucco gli elementi di dati di DataList. Supponendo di usare un Item oggetto o AlternatingItem, si accede all'istanza effettiva ProductsRow associata all'oggetto corrente DataListItem. La DataListItem proprietà s DataItem contiene un riferimento all'oggetto DataRowView , la cui Row proprietà fornisce un riferimento all'oggetto effettivoProductsRow.

Successivamente, si controlla la proprietà dell'istanza ProductsRowUnitPrice . Poiché il campo della UnitPrice tabella Products consente NULL i valori, prima di tentare di accedere alla UnitPrice proprietà, è prima necessario verificare se ha un NULL valore usando il IsUnitPriceNull() metodo . Se il UnitPrice valore non NULLè , si verifica se è minore di $20,00. Se è effettivamente inferiore a $20,00, è necessario 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à Labels BackColor (LabelID.BackColor = Color.Yellow); idealmente, tuttavia, tutte le questioni relative alla visualizzazione devono essere espresse tramite fogli di stile a catena. In realtà, è già disponibile un foglio di stile che fornisce la formattazione desiderata definita in Styles.css - AffordablePriceEmphasis, che è stata creata e descritta nell'esercitazione Formattazione personalizzata basata su dati .

Per applicare la formattazione, è sufficiente impostare le due proprietà dei controlli CssClass Web Etichetta su AffordablePriceEmphasis, come illustrato 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";

Al termine del ItemDataBound gestore eventi, rivedere la Formatting.aspx pagina in un browser. Come illustrato nella figura 2, i prodotti con un prezzo inferiore a $ 20,00 hanno sia il nome che il prezzo evidenziati.

Questi 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)

Nota

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, è stato 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 della formattazione personalizzata a Repeater richiede l'applicazione di proprietà di stile ai controlli Web all'interno dei modelli di Repeater, proprio come nella figura 2.

L'intero articolo prodotto è evidenziato per i prodotti con $20,00

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

Uso delle funzioni di formattazione dall'interno del modello

Nell'esercitazione Uso di TemplateFields nell'esercitazione Controllo GridView è stato illustrato come usare una funzione di formattazione in un modello GridView per applicare 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 fuori 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 illustrare le funzioni di formattazione, lasciare che le informazioni sul prodotto includano il testo [DISCONTINUED] accanto al nome del prodotto se viene interrotto. Inoltre, lasciare che il prezzo sia evidenziato giallo se è minore di $20,00 (come abbiamo fatto nell'esempio ItemDataBound del gestore eventi); se il prezzo è $20,00 o superiore, lasciare che non visualizzi il prezzo effettivo, ma invece il testo, chiama per un preventivo prezzo. La figura 4 mostra una schermata dei prodotti che elencano 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 dollari sostituiti con il testo ,

Figura 4: Per i prodotti costosi, il prezzo viene sostituito con il testo, chiamare per una quotazione prezzo (fare clic per visualizzare l'immagine full-size)

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, chiamare per un preventivo 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 da eseguire come stringa e entrambi devono essere contrassegnati Protected (o Public) per essere richiamati dalla parte 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 DisplayPrice (anziché un unitPriceProductsRow valore scalare). Entrambi gli approcci funzioneranno; tuttavia, se la funzione di formattazione usa valori scalari che possono contenere valori di database NULL ,ad esempio UnitPrice; né ProductNameDiscontinued consenti NULL valori, è necessario prestare particolare attenzione alla 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 . Vale a dire, se si vuole che il metodo accetti il DisplayPrice 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 parametro di input è di tipo Object e che l'istruzione unitPrice condizionale è stata modificata per verificare se unitPrice è DBNull o meno. Inoltre, poiché il unitPrice parametro di input viene passato come Object, deve essere eseguito il cast in un valore decimale.

Passaggio 2: Chiamata della funzione di formattazione dall'elemento 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 alla funzione all'interno della sintassi databinding:

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

Nel controllo Web etichetta di ItemTemplateProductNameLabel DataList viene attualmente visualizzato il nome del prodotto assegnando la relativa Text proprietà al risultato di <%# Eval("ProductName") %>. Per visualizzare il nome e il testo [DISCONTINUED], se necessario, aggiornare la sintassi dichiarativa in modo che assegna invece la Text proprietà il valore del DisplayProductNameAndDiscontinuedStatus metodo. In questo caso, è necessario passare il nome del prodotto e i valori interrotti usando la Eval("columnName") sintassi. 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 parametri di input previsti, ad esempio:

<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 sul Text valore restituito dal DisplayPrice metodo, proprio come abbiamo fatto per visualizzare il nome del prodotto e [DISCONTINUED] testo. Invece di passare come UnitPrice parametro di input scalare, invece di passare l'intera ProductsRow istanza:

<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 sul posto, è necessario un momento per visualizzare lo stato di avanzamento in un browser. Lo schermo dovrebbe essere simile alla figura 5, con i prodotti interrotti, incluso il testo [DISCONTINUED] e i prodotti che costano più di $ 20,00 avendo il loro prezzo sostituito con il testo Chiamare per una quotazione prezzo .

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

Figura 5: Per i prodotti costosi, il prezzo viene sostituito con il testo, chiamare per una quotazione prezzo (Fare clic per visualizzare l'immagine full-size)

Riepilogo

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, che viene generato come ogni record nell'origine ItemDataBound dati è associato a un nuovo 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 restituiscono 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 .

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. I revisori principali per questa esercitazione sono stati Yaakov Ellis, Randy Schmidt e Liz Shulok. Interessati a esaminare i prossimi articoli MSDN? In tal caso, lasciami una riga in mitchell@4GuysFromRolla.com.