Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I den här självstudien går vi igenom exempel på hur vi formaterar utseendet på kontrollerna DataList och Repeater, antingen genom att använda formateringsfunktioner i mallar eller genom att hantera DataBound-händelsen.
Inledning
Som vi såg i föregående självstudiekurs erbjuder DataList ett antal stilrelaterade egenskaper som påverkar dess utseende. I synnerhet såg vi hur du tilldelar standard-CSS-klasser till egenskaperna DataList s HeaderStyle
, ItemStyle
, AlternatingItemStyle
och SelectedItemStyle
. Förutom dessa fyra egenskaper innehåller DataList ett antal andra stilrelaterade egenskaper, till exempel Font
, ForeColor
, BackColor
och BorderWidth
, för att nämna några. Repeater-kontrollen innehåller inga formatrelaterade egenskaper. Alla sådana formatinställningar måste göras direkt inom markeringen i Repeater s-mallarna.
Hur data ska formateras beror dock ofta på själva data. När vi till exempel listar produkter kanske vi vill visa produktinformationen i en ljusgrå teckenfärg om den upphör, eller så kanske vi vill markera UnitsInStock
värdet om det är noll. Som vi såg i tidigare självstudier erbjuder GridView, DetailsView och FormView två olika sätt att formatera deras utseende baserat på deras data:
-
Händelsen
DataBound
skapar en händelsehanterare för lämpligDataBound
händelse som utlöses efter att data har bundits till varje objekt (för GridView varRowDataBound
det händelsen, för DataList och Repeater ärItemDataBound
det händelsen). I den händelsehanteraren kan data som nyss har bundits undersökas och beslut om formatering fattas. Vi har granskat den här tekniken i självstudiekursen Anpassad formatering baserad på data . - Formateringsfunktioner i mallar när du använder TemplateFields i kontrollerna DetailsView eller GridView, eller en mall i FormView-kontrollen, kan vi lägga till en formateringsfunktion i ASP.NET sidans kod bakom-klass, Business Logic Layer eller något annat klassbibliotek som är tillgängligt från webbprogrammet. Den här formateringsfunktionen kan acceptera ett godtyckligt antal indataparametrar, men måste returnera HTML-koden för att återges i mallen. Formateringsfunktioner undersöktes först i självstudiekursen Använda mallfält i GridView Control .
Båda dessa formateringstekniker är tillgängliga med kontrollerna DataList och Repeater. I den här handledningen kommer vi att gå igenom exempel med både teknikerna för båda kontrollerna.
ItemDataBound
Använda händelsehanteraren
När data är bundna till en DataList, antingen från en datakällkontroll eller genom att programmatiskt tilldela data till kontrollens DataSource
-egenskap och anropa dess DataBind()
-metod, utlöses DataList-händelsen DataBinding
, datakällan räknas upp, och varje datapost binds till DataList. För varje post i datakällan skapar DataList ett DataListItem
objekt som sedan är bundet till den aktuella posten. Under den här processen genererar DataList två händelser:
-
ItemCreated
aktiveras efter attDataListItem
har skapats -
ItemDataBound
utlöses efter att den aktuella posten har bundits tillDataListItem
Följande steg beskriver databindningsprocessen för DataList-kontrollen.
Händelsen DataList s
DataBinding
utlösesData är bundna till DataList
För varje post i datakällan
- Skapa ett
DataListItem
objekt -
ItemCreated
Utlös händelsen - Bind ihop posten med
DataListItem
-
ItemDataBound
Utlös händelsen - Lägg till
DataListItem
iItems
-samlingen
- Skapa ett
När data binds till Repeater-kontrollen fortsätter de genom exakt samma stegsekvens. Den enda skillnaden är att istället för DataListItem
-instanser som skapas använder Repeater RepeaterItem
.
Anmärkning
Den skarpsinniga läsaren kan ha märkt en liten avvikelse mellan sekvensen med steg som inträffar när DataList och Repeater är bundna till data jämfört med när GridView är bundet till data. I slutet av databindningsprocessen genererar DataBound
GridView händelsen, men varken DataList- eller Repeater-kontrollen har en sådan händelse. Det beror på att kontrollerna DataList och Repeater skapades i ASP.NET version 1.x innan händelsehanteringsmönstret med föregående och efterföljande nivå hade blivit vanligt.
Precis som med GridView är ett alternativ för formatering baserat på data att skapa en händelsehanterare för ItemDataBound
händelsen. Den här händelsehanteraren skulle inspektera de data som just hade bundits till DataListItem
eller RepeaterItem
och påverka kontrollens formatering efter behov.
För DataList-kontrollen kan formateringsändringar för hela objektet implementeras med hjälp av DataListItem
s-stilrelaterade egenskaper, som inkluderar standarden Font
, ForeColor
, BackColor
, CssClass
och så vidare. För att påverka formateringen av vissa webbkontroller i DataList s-mallen måste vi programmatiskt komma åt och ändra formatet för dessa webbkontroller. Vi såg hur man gjorde detta i handledningen Anpassad formatering baserat på data. Precis som Repeater-kontrollen RepeaterItem
har klassen inga stilrelaterade egenskaper. Därför måste alla formatrelaterade ändringar som görs i en RepeaterItem
i ItemDataBound
händelsehanteraren göras genom programmatisk åtkomst till och uppdatering av webbkontroller i mallen.
ItemDataBound
Eftersom formateringstekniken för DataList och Repeater är praktiskt taget identiska fokuserar vårt exempel på att använda DataList.
Steg 1: Visa produktinformation i datalistan
Innan vi oroar oss för formateringen ska vi först skapa en sida som använder en DataList för att visa produktinformation. I den föregående självstudien skapade vi en DataList vars ItemTemplate
produktnamn, kategori, leverantör, kvantitet per enhet och pris visas. Låt oss upprepa denna funktion i den här handledningen. För att åstadkomma detta kan du antingen återskapa DataList och dess ObjectDataSource från grunden, eller så kan du kopiera över kontrollerna från sidan som skapades i föregående självstudie (Basics.aspx
) och klistra in dem på sidan för den här självstudien (Formatting.aspx
).
När du har replikerat funktionerna DataList och ObjectDataSource från Basics.aspx
till Formatting.aspx
, ta en stund för att ändra DataLists egenskap från ID
till en mer beskrivande DataList1
. Visa sedan DataList i en webbläsare. Som bild 1 visar är den enda formateringsskillnaden mellan varje produkt att bakgrundsfärgen växlar.
Bild 1: Produkterna visas i datalistekontrollen (klicka om du vill visa en bild i full storlek)
I den här självstudien ska vi formatera DataList så att alla produkter med ett pris som är mindre än 20,00 USD har både namnet och enhetspriset markerat gult.
Steg 2: Programmatiskt bestämma värdet för data i ItemDataBound-händelsehanteraren
Eftersom endast de produkter med ett pris under $20.00 kommer att ha den anpassade formateringen tillämpad, måste vi kunna fastställa varje produkts pris. När data binds till en DataList räknar DataList upp posterna i datakällan och skapar för varje post en DataListItem
instans som binder datakällposten till DataListItem
. När den specifika postens data har bundits till det aktuella DataListItem
-objektet utlöses DataListens ItemDataBound
-händelse. Vi kan skapa en händelsehanterare för den här händelsen för att inspektera datavärdena för den aktuella DataListItem
och, baserat på dessa värden, göra nödvändiga formateringsändringar.
Skapa en ItemDataBound
händelse för DataList och lägg till följande kod:
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
}
}
}
Även om begreppet och semantiken bakom DataLists ItemDataBound
händelsehanterare är desamma som de som används av GridViews RowDataBound
händelsehanterare i självstudien Anpassad formatering baserad på data , skiljer sig syntaxen något åt. När händelsen ItemDataBound
utlöses skickas DataListItem
, som just har bundits till data, till den motsvarande händelsehanteraren via e.Item
(istället för e.Row
, som med GridViews RowDataBound
händelsehanterare). DataLists ItemDataBound
händelsehanterare utlöses för varje rad som läggs till i DataList, inklusive sidhuvudrader, sidfotsrader och avgränsarrader. Produktinformationen är dock endast bunden till dataraderna. När vi använder ItemDataBound
händelsen för att inspektera data som är bundna till DataList måste vi därför först se till att vi arbetar med ett dataobjekt. Detta kan du göra genom att kontrollera DataListItem
egenskapen sItemType
, som kan ha något av följande åtta värden:
AlternatingItem
EditItem
Footer
Header
Item
Pager
SelectedItem
Separator
Både Item
och AlternatingItem``DataListItem
utgör DataLists dataenheter. Förutsatt att vi arbetar med en Item
eller AlternatingItem
, kommer vi åt den faktiska ProductsRow
-instansen som var bunden till den aktuella DataListItem
. Egenskapen DataListItem
s DataItem
innehåller en referens till DataRowView
objektet, vars Row
egenskap ger en referens till det faktiska ProductsRow
objektet.
Därefter kontrollerar vi instansens ProductsRow
UnitPrice
egenskap. Eftersom fältet Products table s UnitPrice
tillåter NULL
värden bör vi först kontrollera om den har ett UnitPrice
värde med hjälp av NULL
metoden innan du försöker komma åt IsUnitPriceNull()
egenskapen. Om värdet UnitPrice
inte NULL
är kontrollerar vi om det är mindre än 20,00 USD. Om den verkligen är under 20,00 USD måste vi tillämpa den anpassade formateringen.
Steg 3: Markera produktens namn och pris
När vi vet att en produkts pris är mindre än $ 20,00, allt som återstår är att markera dess namn och pris. För att åstadkomma detta måste vi först programmatiskt referera till etikettkontrollerna i ItemTemplate
som visar produktens namn och pris. Därefter måste de visa en gul bakgrund. Den här formateringsinformationen kan användas genom att direkt ändra egenskaperna Etiketter BackColor
(LabelID.BackColor = Color.Yellow
), men helst bör alla visningsrelaterade frågor uttryckas via sammanhängande formatmallar. Faktum är att vi redan har en formatmall som ger önskad formatering definierad i Styles.css
- AffordablePriceEmphasis
, som skapades och diskuterades i självstudien Anpassad formatering baserat på data .
Om du vill använda formateringen anger du bara de två egenskaperna för Etikettwebbkontroller CssClass
till AffordablePriceEmphasis
, som du ser i följande kod:
// 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";
ItemDataBound
När händelsehanteraren är klar går du tillbaka till Formatting.aspx
sidan i en webbläsare. Som bild 2 visar har dessa produkter med ett pris under $20,00 både sitt namn och pris markerat.
Bild 2: Dessa produkter som är mindre än 20,00 USD är markerade (klicka om du vill visa en bild i full storlek)
Anmärkning
Eftersom DataList återges som en HTML <table>
har dess DataListItem
instanser stilrelaterade egenskaper som kan anges för att tillämpa ett visst format på hela objektet. Om vi till exempel vill markera hela objektet gult när priset var mindre än 20,00 USD kunde vi ha ersatt koden som refererade till etiketterna och ställt in deras CssClass
egenskaper med följande kodrad: e.Item.CssClass = "AffordablePriceEmphasis"
(se bild 3).
De RepeaterItem
som utgör Repeater-kontrollen erbjuder dock inte sådana egenskaper på formatnivå. För att tillämpa anpassad formatering på Repeater krävs därför att formategenskaper tillämpas på webbkontrollerna i Repeater-mallarna, precis som vi gjorde i bild 2.
Bild 3: Hela produktobjektet är markerat för produkter under 20,00 USD (klicka om du vill visa en bild i full storlek)
Använda formateringsfunktioner från mallen
I handledningen Att använda mallfält i GridView-kontrollen såg vi hur man använder en formateringsfunktion i ett GridView-mallfält för att tillämpa anpassad formatering baserat på data som är bundna till GridView-raderna. En formateringsfunktion är en metod som kan anropas från en mall och returnerar HTML som ska genereras i dess ställe. Formateringsfunktioner kan finnas i ASP.NET sidans kod bakom-klass eller centraliseras till klassfiler i App_Code
mappen eller i ett separat klassbiblioteksprojekt. Att flytta formateringsfunktionen från ASP.NET sidans kod bakom-klass är perfekt om du planerar att använda samma formateringsfunktion på flera ASP.NET sidor eller i andra ASP.NET webbprogram.
För att demonstrera formateringsfunktioner ska vi låta produktinformationen innehålla texten [DISCONTINUED] bredvid produktens namn om den upphör. Låt oss också ha priset markerat gult om det är mindre än $ 20,00 (som vi gjorde i ItemDataBound
händelsehanterarens exempel); om priset är $ 20.00 eller högre, låt oss inte visa det faktiska priset, utan i stället texten, Vänligen anropa för en pris offert. Bild 4 visar en skärmbild av produktlistan med dessa formateringsregler tillämpade.
Bild 4: För dyra produkter ersätts priset med texten. Anropa efter en prisoffert (Klicka om du vill visa en bild i full storlek)
Steg 1: Skapa formateringsfunktionerna
I det här exemplet behöver vi två formateringsfunktioner, en som visar produktnamnet tillsammans med texten [DISCONTINUED], om det behövs, och en annan som visar antingen ett markerat pris om det är mindre än 20,00 USD eller texten, Anropa annars för en prisoffert. Låt oss skapa dessa funktioner i kod-bakom-klassen på ASP.NET-sidan och namnge dem DisplayProductNameAndDiscontinuedStatus
och DisplayPrice
. Båda metoderna måste returnera HTML-koden för att återges som en sträng och båda måste markeras Protected
(eller Public
) för att kunna anropas från ASP.NET sidans deklarativa syntaxdel. Koden för dessa två metoder följer:
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>";
}
Observera att DisplayProductNameAndDiscontinuedStatus
metoden accepterar värdena för datafälten productName
och discontinued
som skalära värden, medan DisplayPrice
metoden accepterar en ProductsRow
instans (i stället för ett unitPrice
skalärt värde). Endera metoden fungerar. Men om formateringsfunktionen fungerar med skalära värden som kan innehålla databasvärden NULL
(till exempel UnitPrice
; varken ProductName
eller Discontinued
tillåtna NULL
värden), måste du vara särskilt noga med att hantera dessa skalära indata.
I synnerhet måste indataparametern vara av typen Object
eftersom det inkommande värdet kan vara en DBNull
instans i stället för den förväntade datatypen. Dessutom måste en kontroll göras för att avgöra om det inkommande värdet är ett databasvärde NULL
eller inte. Om vi vill DisplayPrice
att metoden ska acceptera priset som ett skalärt värde måste vi alltså använda följande kod:
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>";
}
Observera att unitPrice
-parametern är av typen Object
och att den villkorsstyrda satsen har ändrats för att avgöra om unitPrice
är DBNull
eller inte. Eftersom indataparametern skickas som ett unitPrice
måste den dessutom Object
omvandlas till ett decimalvärde.
Steg 2: Anropa formateringsfunktionen från DataList s ItemTemplate
När formateringsfunktionerna har lagts till i vår ASP.NET-sidans kod-bakom-klassen är allt som återstår att anropa dessa formateringsfunktioner från DataListens ItemTemplate
. Om du vill anropa en formateringsfunktion från en mall placerar du funktionsanropet inom syntaxen för databindning:
<%# MethodName(inputParameter1, inputParameter2, ...) %>
I DataList s ItemTemplate
ProductNameLabel
visar kontrollen Etikettwebb för närvarande produktens namn genom att tilldela dess Text
egenskap resultatet av <%# Eval("ProductName") %>
. För att se till att namnet visas tillsammans med texten [UTGÅNGEN], uppdaterar du vid behov den deklarativa syntaxen så att egenskapen Text
istället får värdet från DisplayProductNameAndDiscontinuedStatus
-metoden. När vi gör det måste vi skicka in produktens namn och utgångna värden med hjälp av syntaxen Eval("columnName")
.
Eval
returnerar ett värde av typen Object
, men DisplayProductNameAndDiscontinuedStatus
metoden förväntar sig indataparametrar av typen String
och Boolean
därför måste vi omvandla värdena som returneras av Eval
metoden till de förväntade indataparametertyperna, så här:
<h4>
<asp:Label ID="ProductNameLabel" runat="server"
Text='<%# DisplayProductNameAndDiscontinuedStatus((string) Eval("ProductName"),
(bool) Eval("Discontinued")) %>'>
</asp:Label>
</h4>
För att visa priset kan vi helt enkelt ange UnitPriceLabel
egenskapen Etikett till Text
det värde som returneras av DisplayPrice
metoden, precis som vi gjorde för att visa produktens namn och texten [DISCONTINUED]. Men i stället för att skicka in UnitPrice
som en skalär indataparameter skickar vi i stället hela ProductsRow
instansen:
<asp:Label ID="UnitPriceLabel" runat="server"
Text='<%# DisplayPrice((Northwind.ProductsRow)
((System.Data.DataRowView) Container.DataItem).Row) %>'>
</asp:Label>
När anropen till formateringsfunktionerna är på plats, ta en stund och titta på vår framsteg i en webbläsare. Skärmen bör se ut ungefär som i bild 5, med de produkter som har utgått inkluderande texten [DISCONTINUED] och de produkter som kostar mer än 20,00 $ ha deras pris ersatt med texten Ring för prisförslag.
Bild 5: För dyra produkter ersätts priset med texten. Anropa efter en prisoffert (Klicka om du vill visa en bild i full storlek)
Sammanfattning
Formatering av innehållet i en DataList- eller Repeater-kontroll baserat på data kan utföras med hjälp av två tekniker. Den första tekniken är att skapa en händelsehanterare för ItemDataBound
händelsen, som utlöses när varje post i datakällan är bunden till en ny DataListItem
eller RepeaterItem
.
ItemDataBound
I händelsehanteraren kan det aktuella objektets data undersökas och sedan kan formateringen tillämpas på innehållet i mallen eller, för DataListItem
s, på hela själva objektet.
Du kan också använda anpassad formatering via formateringsfunktioner. En formateringsfunktion är en metod som kan anropas från mallarna DataList eller Repeater som returnerar HTML-koden som ska genereras i dess ställe. Ofta bestäms HTML-koden som returneras av en formateringsfunktion av de värden som är bundna till det aktuella objektet. Dessa värden kan skickas till formateringsfunktionen, antingen som skalära värden eller genom att skicka in hela objektet som är bundet till objektet (till exempel instansen ProductsRow
).
Lycka till med programmerandet!
Om författaren
Scott Mitchell, författare till sju ASP/ASP.NET-böcker och grundare av 4GuysFromRolla.com, har arbetat med Microsofts webbtekniker sedan 1998. Scott arbetar som oberoende konsult, tränare och författare. Hans senaste bok är Sams Teach Yourself ASP.NET 2.0 på 24 timmar. Han kan nås på mitchell@4GuysFromRolla.com.
Särskilt tack till
Den här självstudieserien granskades av många användbara granskare. Huvudgranskare för den här självstudien var Yaakov Ellis, Randy Schmidt och Liz Shulok. Vill du granska mina kommande MSDN-artiklar? Om så är fallet, hör av dig på mitchell@4GuysFromRolla.com.