Formátování ovládacích prvků DataList a Repeater na základě dat (C#)
V tomto kurzu si projdeme příklady formátování vzhledu ovládacích prvků DataList a Repeater, a to buď pomocí funkcí formátování v šablonách, nebo zpracováním události DataBound.
Úvod
Jak jsme viděli v předchozím kurzu, DataList nabízí řadu vlastností souvisejících se stylem, které ovlivňují jeho vzhled. Konkrétně jsme viděli, jak přiřadit výchozí třídy CSS vlastnostem DataList s HeaderStyle
, ItemStyle
, AlternatingItemStyle
a SelectedItemStyle
. Kromě těchto čtyř vlastností obsahuje Seznam dat řadu dalších vlastností souvisejících se styly, například Font
, ForeColor
, BackColor
a BorderWidth
. Ovládací prvek Repeater neobsahuje žádné vlastnosti související se stylem. Všechna taková nastavení stylu musí být provedena přímo v rámci značek v šablonách Repeater s.
Způsob formátování dat ale často závisí na samotných datech. Například při výpisu produktů můžeme chtít zobrazit informace o produktu ve světle šedé barvě písma, pokud je ukončeno, nebo můžeme chtít zvýraznit UnitsInStock
hodnotu, pokud je nulová. Jak jsme viděli v předchozích kurzech, GridView, DetailsView a FormView nabízejí dva různé způsoby formátování vzhledu na základě dat:
- Událost
DataBound
vytvoří obslužnou rutinu události pro příslušnouDataBound
událost, která se aktivuje poté, co jsou data svázaná s každou položkou (pro GridView to bylaRowDataBound
událost; pro DataList a Repeater jeItemDataBound
to událost). V této obslužné rutině události je možné zkoumat právě svázaná data a provádět rozhodnutí o formátování. Tuto techniku jsme prozkoumali v kurzu Vlastní formátování založené na datech . - Formátování funkcí v šablonách při použití TemplateFields v ovládacích prvcích DetailsView nebo GridView nebo šablony v ovládacím prvku FormView můžeme přidat funkci formátování do třídy kódu ASP.NET stránky s kódu na pozadí, vrstvy obchodní logiky nebo jakékoli jiné knihovny tříd, která je přístupná z webové aplikace. Tato funkce formátování může přijmout libovolný počet vstupních parametrů, ale musí vrátit HTML, aby se vykreslovat v šabloně. Funkce formátování byly poprvé prozkoumány v kurzu Using TemplateFields v ovládacím prvku GridView .
Obě tyto techniky formátování jsou k dispozici s ovládacími prvky DataList a Repeater. V tomto kurzu si projdeme příklady s použitím obou technik pro oba ovládací prvky.
Použití obslužné rutinyItemDataBound
události
Když jsou data vázána na DataList, buď z ovládacího prvku zdroje dat nebo prostřednictvím programového přiřazení dat k vlastnosti ovládacího prvku s DataSource
a volání jeho DataBind()
metody, událost DataList s DataBinding
se aktivuje, zdroj dat výčtu a každý datový záznam je vázán na DataList. Pro každý záznam ve zdroji dat vytvoří DataListItem
DataList objekt, který je pak svázán s aktuálním záznamem. Během tohoto procesu vyvolá DataList dvě události:
ItemCreated
se aktivuje po vytvoření objektuDataListItem
ItemDataBound
se aktivuje poté, co je aktuální záznam vázán naDataListItem
Následující kroky popisují proces datové vazby pro ovládací prvek DataList.
Událost DataList s se
DataBinding
aktivuje.Data jsou svázaná s seznamem DataList.
Pro každý záznam ve zdroji dat
- Vytvoření objektu
DataListItem
- Aktivujte událost.
ItemCreated
- Vytvořte vazbu záznamu na
DataListItem
- Aktivujte událost.
ItemDataBound
- Přidání objektu
DataListItem
Items
do kolekce
- Vytvoření objektu
Při vytváření vazby dat s ovládacím prvkem Repeater prochází přesně stejnou posloupností kroků. Jediným rozdílem DataListItem
je, že místo vytváření instancí používá RepeaterItem
Repeater s.
Poznámka
Chytný čtenář si mohl všimnout mírné anomálie mezi posloupností kroků, které se objeví, když DataList a Repeater jsou svázány s daty a kdy GridView je svázán s daty. Na konci procesu datové vazby DataBound
GridView vyvolá událost, ale ani Ovládací prvek DataList ani Repeater takovou událost nemá. Důvodem je to, že ovládací prvky DataList a Repeater byly vytvořeny zpět v časovém rámci ASP.NET 1.x, před tím, než se vzor obslužné rutiny událostí před a po úrovni stal běžným.
Stejně jako u GridView je jednou z možností formátování na základě dat vytvoření obslužné rutiny události pro ItemDataBound
událost. Tato obslužná rutina události by zkontrolovala data, která byla právě svázaná s DataListItem
nebo RepeaterItem
, a podle potřeby ovlivnila formátování ovládacího prvku.
U ovládacího prvku DataList lze změny formátování pro celou položku implementovat pomocí DataListItem
vlastností souvisejících se stylem s, mezi které patří standardní Font
, ForeColor
, BackColor
, CssClass
atd. Chcete-li ovlivnit formátování určitých webových ovládacích prvků v šabloně DataList s, musíme programově přistupovat k těmto webovým ovládacím prvkům a upravovat je. Zjistili jsme, jak toho dosáhnout, v kurzu Vlastní formátování založené na datech . Stejně jako u ovládacího prvku RepeaterItem
Repeater nemá třída žádné vlastnosti související se stylem; proto všechny změny související se stylem provedené v ItemDataBound
obslužné RepeaterItem
rutině události musí být provedeny programovým přístupem k webovým ovládacím prvkům a jejich aktualizací v rámci šablony.
Vzhledem k tomu, že ItemDataBound
technika formátování pro DataList a Repeater jsou prakticky identická, náš příklad se zaměří na použití seznamu DataList.
Krok 1: Zobrazení informací o produktu v seznamu DataList
Než si začneme dělat starosti s formátováním, pojďme nejprve vytvořit stránku, která k zobrazení informací o produktu používá DataList. V předchozím kurzu jsme vytvořili DataList, který ItemTemplate
zobrazoval názvy jednotlivých produktů, kategorie, dodavatele, množství na jednotku a cenu. Pojďme si tuto funkci zopakovat v tomto kurzu. K tomu můžete buď znovu vytvořit DataList a jeho ObjectDataSource od začátku, nebo můžete tyto ovládací prvky zkopírovat ze stránky vytvořené v předchozím kurzu (Basics.aspx
) a vložit je na stránku pro tento kurz (Formatting.aspx
).
Po replikaci funkcí DataList a ObjectDataSource z Basics.aspx
do Formatting.aspx
, chvíli trvat, než změníte vlastnost DataList s ID
z DataList1
na popisnější ItemDataBoundFormattingExample
. Dále si v prohlížeči zobrazte DataList. Jak ukazuje obrázek 1, jediným rozdílem ve formátování mezi jednotlivými produkty je střídavá barva pozadí.
Obrázek 1: Produkty jsou uvedeny v ovládacím prvku DataList (kliknutím zobrazíte obrázek v plné velikosti)
Pro účely tohoto kurzu naformátujte DataList tak, aby všechny produkty s cenou nižší než 20,00 USD měly svůj název i jednotkovou cenu zvýrazněné žlutě.
Krok 2: Programové určení hodnoty dat v obslužné rutině události ItemDataBound
Vzhledem k tomu, že vlastní formátování bude použito pouze u produktů s cenou nižší než 20,00 USD, musíme být schopni určit cenu každého produktu. Při vytváření vazby dat se seznamem DataList vytvoří výčet záznamů ve svém zdroji dat a pro každý záznam vytvoří DataListItem
instanci, která vytvoří vazbu záznamu zdroje dat na DataListItem
. Jakmile jsou data konkrétního záznamu s svázána s aktuálním DataListItem
objektem, aktivuje se událost DataList s ItemDataBound
. Pro tuto událost můžeme vytvořit obslužnou rutinu události, která zkontroluje aktuální hodnoty DataListItem
dat a na základě těchto hodnot provede potřebné změny formátování.
Vytvořte ItemDataBound
událost pro DataList a přidejte následující kód:
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
}
}
}
Zatímco koncept a sémantika obslužné rutiny události DataList s ItemDataBound
jsou stejné jako ty, které používá obslužná rutina události GridView s RowDataBound
v kurzu Vlastní formátování založené na datech , syntaxe se mírně liší. Když se ItemDataBound
událost aktivuje, DataListItem
je právě svázaná s daty předána odpovídající obslužné rutině události prostřednictvím e.Item
(místo e.Row
, jako u obslužné rutiny události GridView s RowDataBound
). Obslužná rutina události DataList s ItemDataBound
se aktivuje pro každý řádek přidaný do seznamu DataList, včetně řádků záhlaví, řádků zápatí a řádků oddělovače. Informace o produktu jsou však vázány pouze na řádky dat. Proto při použití ItemDataBound
události ke kontrole dat vázaný na seznam DataList musíme nejprve zajistit, že pracujeme s datovou položkou. Toho lze dosáhnout kontrolou DataListItem
vlastnosti sItemType
, která může mít jednu z následujících osmi hodnot:
AlternatingItem
EditItem
Footer
Header
Item
Pager
SelectedItem
Separator
Datové položky DataList s se vytřidí AlternatingItem``DataListItem
jak Item
a tak. Za předpokladu, že pracujeme s Item
nebo AlternatingItem
, přistupujeme ke skutečné ProductsRow
instanci, která byla vázána na aktuální DataListItem
. Vlastnost DataListItem
s DataItem
obsahuje odkaz na DataRowView
objekt, jehož Row
vlastnost poskytuje odkaz na skutečný ProductsRow
objekt.
Dále zkontrolujeme ProductsRow
vlastnost instance s UnitPrice
. Vzhledem k tomu, že pole Tabulky UnitPrice
Produkty umožňuje NULL
hodnoty, měli bychom před pokusem o přístup UnitPrice
k vlastnosti nejprve zkontrolovat, jestli má NULL
hodnotu pomocí IsUnitPriceNull()
metody . Pokud hodnota UnitPrice
není NULL
, zkontrolujeme, jestli je menší než 20,00 USD. Pokud je skutečně méně než 20,00 USD, musíme použít vlastní formátování.
Krok 3: Zvýraznění názvu a ceny produktu
Jakmile víme, že cena produktu je nižší než 20,00 USD, zbývá zvýraznit jeho název a cenu. Abychom toho dosáhli, musíme nejprve programově odkazovat na ovládací prvky Label v ovládacích ItemTemplate
prvcích, které zobrazují název a cenu produktu. Dále musíme, aby se zobrazilo žluté pozadí. Tyto informace o formátování lze použít přímou úpravou vlastností Popisky BackColor
(LabelID.BackColor = Color.Yellow
). V ideálním případě by však všechny skutečnosti související se zobrazením měly být vyjádřeny prostřednictvím kaskádových šablon stylů. Ve skutečnosti už máme šablonu stylů, která poskytuje požadované formátování definované v Styles.css
- AffordablePriceEmphasis
nástroji , který byl vytvořen a popsán v kurzu Vlastní formátování založené na datech .
Pokud chcete použít formátování, jednoduše nastavte vlastnosti dvou ovládacích prvků CssClass
Label Web na AffordablePriceEmphasis
hodnotu , jak je znázorněno v následujícím kódu:
// 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";
Po dokončení obslužné ItemDataBound
rutiny události znovu přejděte na Formatting.aspx
stránku v prohlížeči. Jak znázorňuje obrázek 2, u produktů s cenou nižší než 20,00 USD je zvýrazněný název i cena.
Obrázek 2: Tyto produkty menší než 20,00 USD jsou zvýrazněné (kliknutím zobrazíte obrázek v plné velikosti).
Poznámka
Vzhledem k tomu, dataList je vykreslen jako HTML <table>
, jeho DataListItem
instance mají vlastnosti související se stylem, které lze nastavit tak, aby použily konkrétní styl na celou položku. Pokud bychom například chtěli zvýraznit celou položku žlutě, když její cena byla nižší než 20,00 Usd, mohli bychom nahradit kód, který odkazoval na popisky, a nastavit jejich CssClass
vlastnosti následujícím řádkem kódu: e.Item.CssClass = "AffordablePriceEmphasis"
(viz obrázek 3).
S RepeaterItem
, které tvoří ovládací prvek Repeater, však nenabízí takové vlastnosti na úrovni stylu. Proto použití vlastního formátování na repeater vyžaduje použití vlastností stylu na webové ovládací prvky v rámci šablon Repeater s, stejně jako jsme to udělali na obrázku 2.
Obrázek 3: Celá položka produktu je zvýrazněná pro produkty do 20,00 USD (kliknutím zobrazíte obrázek v plné velikosti).
Použití formátačních funkcí v rámci šablony
V kurzu Použití templateFields v ovládacím prvku GridView jsme viděli, jak použít funkci formátování v rámci GridView TemplateField k použití vlastního formátování založeného na datech svázaných s řádky GridView. Formátovací funkce je metoda, kterou lze vyvolat ze šablony a vrátí kód HTML, který se má vysílal místo této šablony. Formátovací funkce se mohou nacházet ve třídě ASP.NET kódu stránky nebo mohou být centralizované do souborů třídy ve App_Code
složce nebo v samostatném projektu knihovny tříd. Přesunutí funkce formátování mimo třídu kódu na pozadí stránky ASP.NET je ideální, pokud plánujete používat stejnou funkci formátování ve více ASP.NET stránkách nebo v jiných ASP.NET webových aplikacích.
Chcete-li předvést funkce formátování, nechte informace o produktu zahrnout text [UKONČENO] vedle názvu produktu, pokud je ukončen. Nechte také žlutě zvýraznit cenu, pokud je menší než 20,00 USD (jako jsme to udělali v příkladu ItemDataBound
obslužné rutiny události). Pokud je cena 20 USD nebo vyšší, nezobrazí se skutečná cena, ale místo toho text: Zavolejte prosím pro cenovou nabídku. Obrázek 4 ukazuje snímek obrazovky seznamu produktů s těmito pravidly formátování.
Obrázek 4: U drahých produktů je cena nahrazena textem, zavolejte prosím o cenovou nabídku (kliknutím zobrazíte obrázek v plné velikosti).
Krok 1: Vytvoření formátovací funkce
V tomto příkladu potřebujeme dvě formátovací funkce, jednu, která v případě potřeby zobrazí název produktu spolu s textem [DISCONTINUED] a druhou, která zobrazí buď zvýrazněnou cenu, pokud je menší než 20 USD, nebo text. V opačném případě zadejte cenovou nabídku. Pojďme tyto funkce vytvořit ve třídě kódu ASP.NET stránky a pojmenovat je DisplayProductNameAndDiscontinuedStatus
a DisplayPrice
. Obě metody musí vrátit KÓD HTML, aby se vykreslily jako řetězec, a obě musí být označeny Protected
(nebo Public
) , aby se vyvolaly z části deklarativní syntaxe ASP.NET stránky. Kód pro tyto dvě metody je následující:
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>";
}
Všimněte si DisplayProductNameAndDiscontinuedStatus
, že metoda přijímá hodnoty datových productName
polí a discontinued
jako skalární hodnoty, zatímco DisplayPrice
metoda přijímá ProductsRow
instanci (nikoli unitPrice
skalární hodnotu). Oba přístupy budou fungovat; Pokud však funkce formátování pracuje se skalárními hodnotami, které mohou obsahovat databázové NULL
hodnoty (například UnitPrice
; ani ProductName
Discontinued
nepovolují NULL
hodnoty), je třeba při zpracování těchto skalárních vstupů věnovat zvláštní pozornost.
Vstupní parametr musí být typu Object
, protože příchozí hodnota může být DBNull
instance místo očekávaného datového typu. Kromě toho je nutné provést kontrolu, která určí, zda je příchozí hodnota hodnotou databáze NULL
. To znamená, že pokud chceme DisplayPrice
, aby metoda přijímala cenu jako skalární hodnotu, museli bychom použít následující kód:
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>";
}
Všimněte si unitPrice
, že vstupní parametr je typu Object
a že podmíněný příkaz byl upraven tak, aby se zjistilo, jestli unitPrice
je DBNull
nebo není. Vzhledem k unitPrice
tomu, že vstupní parametr je předán jako Object
, musí být přetypován na desetinnou hodnotu.
Krok 2: Volání funkce formátování z objektu DataList s ItemTemplate
Po přidání funkcí formátování do naší třídy kódu stránky ASP.NET zbývá jen vyvolat tyto funkce formátování z DataList s ItemTemplate
. Pokud chcete volat funkci formátování ze šablony, umístěte volání funkce do syntaxe vazby dat:
<%# MethodName(inputParameter1, inputParameter2, ...) %>
V objektu DataList s ProductNameLabel
ItemTemplate
ovládací prvek Label Web aktuálně zobrazuje název produktu přiřazením jeho Text
vlastnosti výsledek .<%# Eval("ProductName") %>
Aby se zobrazil název a text [DISCONTINUED], v případě potřeby aktualizujte deklarativní syntaxi tak, aby místo toho vlastnost přiřazovala Text
hodnotu DisplayProductNameAndDiscontinuedStatus
metody. Při tom musíme předat název produktu a ukončit hodnoty pomocí Eval("columnName")
syntaxe. Eval
vrátí hodnotu typu Object
, ale DisplayProductNameAndDiscontinuedStatus
metoda očekává vstupní parametry typu String
a Boolean
; proto musíme hodnoty vrácené metodou Eval
přetypovat na očekávané typy vstupních parametrů, například takto:
<h4>
<asp:Label ID="ProductNameLabel" runat="server"
Text='<%# DisplayProductNameAndDiscontinuedStatus((string) Eval("ProductName"),
(bool) Eval("Discontinued")) %>'>
</asp:Label>
</h4>
K zobrazení ceny můžeme jednoduše nastavit UnitPriceLabel
vlastnost Label s Text
na hodnotu vrácenou metodou DisplayPrice
, stejně jako jsme to udělali pro zobrazení názvu produktu a textu [DISCONTINUED]. Místo předání UnitPrice
jako skalárního vstupního parametru ale předáváme celou ProductsRow
instanci:
<asp:Label ID="UnitPriceLabel" runat="server"
Text='<%# DisplayPrice((Northwind.ProductsRow)
((System.Data.DataRowView) Container.DataItem).Row) %>'>
</asp:Label>
Po volání formátovací funkce se chvíli podívejte, jak postupujeme v prohlížeči. Vaše obrazovka by měla vypadat podobně jako na obrázku 5. Ukončené produkty včetně textu [UKONČENO] a produkty s cenou vyšší než 20 USD a jejich cena byla nahrazena textem Prosím volejte pro cenovou nabídku .
Obrázek 5: U drahých produktů je cena nahrazena textem, zavolejte prosím pro cenovou nabídku (kliknutím zobrazíte obrázek v plné velikosti).
Souhrn
Formátování obsahu ovládacího prvku DataList nebo Repeater na základě dat lze provést pomocí dvou technik. První technikou je vytvoření obslužné rutiny události pro ItemDataBound
událost, která se aktivuje, když je každý záznam ve zdroji dat vázaný na nový DataListItem
nebo RepeaterItem
. V obslužné rutině ItemDataBound
události je možné prozkoumat data aktuální položky a pak formátování použít pro obsah šablony nebo pro DataListItem
celou položku.
Případně je možné vlastní formátování realizovat prostřednictvím formátovacích funkcí. Formátovací funkce je metoda, kterou lze vyvolat ze šablon DataList nebo Repeater, která místo této šablony vrací kód HTML. Kód HTML vrácený formátovací funkcí je často určen hodnotami svázanými s aktuální položkou. Tyto hodnoty lze předat funkci formátování, a to buď jako skalární hodnoty, nebo předáním celého objektu vázaného na položku (například ProductsRow
instance).
Všechno nejlepší na programování!
O autorovi
Scott Mitchell, autor sedmi knih o ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, školitel a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Můžete ho zastihnout na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na adrese http://ScottOnWriting.NET.
Zvláštní poděkování
Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavními recenzenty pro tento kurz byli Yaakov Ellis, Randy Schmidt a Liz Shulok. Chtěli byste si projít své nadcházející články na webu MSDN? Pokud ano, dejte mi řádek na mitchell@4GuysFromRolla.com.