Zobrazení souhrnných informací v zápatí prvku GridView (C#)
Scott Mitchell
Souhrnné informace se často zobrazují v dolní části sestavy v souhrnném řádku. Ovládací prvek GridView může obsahovat řádek zápatí, do kterého můžeme prostřednictvím kódu programu vložit agregovaná data. V tomto kurzu se dozvíte, jak zobrazit agregovaná data v tomto řádku zápatí.
Úvod
Kromě zobrazení cen jednotlivých produktů, jednotek skladových jednotek, jednotek na objednávkách a pořadí může být uživatel také zajímat agregované informace, jako je průměrná cena, celkový počet jednotek na skladě atd. Tyto souhrnné informace se často zobrazují v dolní části sestavy v souhrnném řádku. Ovládací prvek GridView může obsahovat řádek zápatí, do kterého můžeme prostřednictvím kódu programu vložit agregovaná data.
Tento úkol představuje tři výzvy:
- Konfigurace prvku GridView pro zobrazení řádku zápatí
- Určení souhrnných dat; To znamená, jak vypočítáme průměrnou cenu nebo celkový počet jednotek v zásobách?
- Vložení souhrnných dat do příslušných buněk řádku zápatí
V tomto kurzu se dozvíme, jak tyto výzvy překonat. Konkrétně vytvoříme stránku se seznamem kategorií v rozevíracím seznamu s produkty vybraných kategorií zobrazenými v objektu GridView. GridView bude obsahovat řádek zápatí, který zobrazuje průměrnou cenu a celkový počet jednotek na skladě a pořadí pro produkty v dané kategorii.
Obrázek 1: Souhrnné informace se zobrazují v řádku zápatí GridView (kliknutím zobrazíte obrázek v plné velikosti).
Tento kurz s kategorií produktů master/detail interface vychází z konceptů popsaných v dřívějším kurzu Master/Detail Filtering With a DropDownList . Pokud jste ještě neprobrali předchozí kurz, udělejte to prosím předtím, než budete pokračovat s tímto kurzem.
Krok 1: Přidání rozevíracího seznamu kategorií a produktů GridView
Než se začneme věnovat přidávání souhrnných informací do zápatí GridView, pojďme nejprve vytvořit hlavní/podrobnou sestavu. Po dokončení tohoto prvního kroku se podíváme na to, jak zahrnout souhrnná data.
Začněte otevřením SummaryDataInFooter.aspx
stránky ve CustomFormatting
složce. Přidejte ovládací prvek DropDownList a nastavte jeho ID
hodnotu Categories
. Dále klikněte na odkaz Zvolit zdroj dat z inteligentní značky DropDownList a zvolte možnost přidat nový ObjectDataSource s názvem CategoriesDataSource
, který vyvolá metodu CategoriesBLL
třídy GetCategories()
.
Obrázek 2: Přidání nového objektu ObjectDataSource s názvem CategoriesDataSource
(kliknutím zobrazíte obrázek s plnou velikostí)
Obrázek 3: Mít ObjectDataSource Vyvolání CategoriesBLL
metody třídy GetCategories()
(kliknutím zobrazíte obrázek plné velikosti)
Po konfiguraci ObjectDataSource nás průvodce vrátí do Průvodce konfigurací zdroje dat DropDownList, ze kterého musíme určit, jaká hodnota datového pole by měla být zobrazena a která by měla odpovídat hodnotě rozevíracího seznamu ListItem
. Zobrazí se CategoryName
pole a použije CategoryID
se jako hodnota.
Obrázek 4: Použití CategoryName
polí a CategoryID
polí jako Text
a Value
pro ListItem
s (kliknutím zobrazíte obrázek v plné velikosti)
V tuto chvíli máme rozevírací seznam (Categories
), který uvádí kategorie v systému. Teď potřebujeme přidat GridView, který vypíše produkty, které patří do vybrané kategorie. Než to ale uděláme, chvíli se podívejte na zaškrtávací políčko Povolit autoPostBack v inteligentní značce DropDownList. Jak je popsáno v kurzu Filtrování předlohy/podrobností pomocí rozevíracího seznamu , nastavením vlastnosti DropDownList AutoPostBack
na true
stránku se publikuje zpět při každé změně hodnoty DropDownList. To způsobí, že se GridView aktualizuje a zobrazí se produkty pro nově vybranou kategorii. AutoPostBack
Pokud je vlastnost nastavená na false
(výchozí), změna kategorie nezpůsobí postback, a proto neaktualizuje uvedené produkty.
Obrázek 5: Zaškrtněte políčko Povolit funkci AutoPostBack v inteligentní značce rozevíracího seznamu (kliknutím zobrazíte obrázek v plné velikosti).
Přidejte na stránku ovládací prvek GridView, aby se zobrazily produkty pro vybranou kategorii. Nastavte Objekt GridView ID
ProductsInCategory
a vytvořte vazbu na nový ObjectDataSource s názvem ProductsInCategoryDataSource
.
Obrázek 6: Přidání nového objektu ObjectDataSource s názvem ProductsInCategoryDataSource
(kliknutím zobrazíte obrázek s plnou velikostí)
Nakonfigurujte ObjectDataSource tak, aby vyvolal metodu ProductsBLL
GetProductsByCategoryID(categoryID)
třídy.
Obrázek 7: Vyvolání GetProductsByCategoryID(categoryID)
metody ObjectDataSource (kliknutím zobrazíte obrázek s plnou velikostí)
Vzhledem k tomu, že GetProductsByCategoryID(categoryID)
metoda přebírá vstupní parametr, můžeme v posledním kroku průvodce zadat zdroj hodnoty parametru. Chcete-li zobrazit tyto produkty z vybrané kategorie, mají parametr načítaný z rozevíracího Categories
seznamu.
Obrázek 8: Získání hodnoty parametru categoryID
z rozevíracího seznamu Vybraných kategorií (kliknutím zobrazíte obrázek s plnou velikostí)
Po dokončení průvodce Bude GridView mít BoundField pro každý z vlastností produktu. Pojďme tyto pole BoundField vyčistit, aby se zobrazily pouze ProductName
pole , UnitPrice
, UnitsInStock
a UnitsOnOrder
BoundFields. Nebojte se přidat všechna nastavení na úrovni pole do zbývajících polí BoundFields (například formátování UnitPrice
jako měny). Po provedení těchto změn by deklarativní kód GridView měl vypadat nějak takto:
<asp:GridView ID="ProductsInCategory" runat="server"
AutoGenerateColumns="False" DataKeyNames="ProductID"
DataSourceID="ProductsInCategoryDataSource" EnableViewState="False">
<Columns>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
HeaderText="Price"
HtmlEncode="False" SortExpression="UnitPrice">
<ItemStyle HorizontalAlign="Right" />
</asp:BoundField>
<asp:BoundField DataField="UnitsInStock"
HeaderText="Units In Stock" SortExpression="UnitsInStock">
<ItemStyle HorizontalAlign="Right" />
</asp:BoundField>
<asp:BoundField DataField="UnitsOnOrder"
HeaderText="Units On Order" SortExpression="UnitsOnOrder">
<ItemStyle HorizontalAlign="Right" />
</asp:BoundField>
</Columns>
</asp:GridView>
V tuto chvíli máme plně funkční hlavní/podrobnou sestavu, která zobrazuje název, jednotkovou cenu, jednotky na skladě a jednotky v objednávce pro produkty, které patří do vybrané kategorie.
Obrázek 9: Získání hodnoty parametru categoryID
z rozevíracího seznamu Vybraných kategorií (kliknutím zobrazíte obrázek s plnou velikostí)
Krok 2: Zobrazení zápatí v objektu GridView
Ovládací prvek GridView může zobrazit řádek záhlaví i zápatí. Tyto řádky se zobrazí v závislosti na hodnotách a vlastnostechShowHeader
, v uvedeném pořadí, s ShowHeader
výchozím nastavením true
a ShowFooter
na false
.ShowFooter
Chcete-li zahrnout zápatí v GridView jednoduše nastavit jeho ShowFooter
vlastnost na true
.
Obrázek 10: Nastavení vlastnosti GridView ShowFooter
na true
(Kliknutím zobrazíte obrázek v plné velikosti)
Řádek zápatí obsahuje buňku pro každé pole definované v objektu GridView; tyto buňky jsou však ve výchozím nastavení prázdné. Chvilku si prohlédněte průběh v prohlížeči. Vlastnost nyní nastavena ShowFooter
na true
, GridView obsahuje prázdný řádek zápatí.
Obrázek 11: Objekt GridView teď obsahuje řádek zápatí (kliknutím zobrazíte obrázek v plné velikosti).
Řádek zápatí na obrázku 11 nevyniká, protože má bílé pozadí. Pojďme vytvořit FooterStyle
třídu CSS, která Styles.css
určuje tmavě červené pozadí a pak nakonfigurujeme GridView.skin
soubor Skin v motivu DataWebControls
pro přiřazení této třídy CSS k Vlastnosti GridViewFooterStyle
CssClass
. Pokud potřebujete střídat skiny a motivy, vraťte se k kurzu Zobrazení dat pomocí ObjectDataSource .
Začněte přidáním následující třídy CSS do Styles.css
:
.FooterStyle
{
background-color: #a33;
color: White;
text-align: right;
}
FooterStyle
Třída CSS je podobná stylu jako HeaderStyle
třída, i když HeaderStyle
barva pozadí je jemně tmavší a její text se zobrazuje tučně. Text v zápatí je navíc zarovnaný doprava, zatímco text záhlaví je zarovnaný na střed.
Chcete-li přidružit tuto třídu CSS ke zápatí každého Objektu GridView, otevřete GridView.skin
soubor v motivu DataWebControls
a nastavte FooterStyle
's CssClass
vlastnost. Po přidání kódu souboru by měl vypadat takto:
<asp:GridView runat="server" CssClass="DataWebControlStyle">
<AlternatingRowStyle CssClass="AlternatingRowStyle" />
<RowStyle CssClass="RowStyle" />
<HeaderStyle CssClass="HeaderStyle" />
<FooterStyle CssClass="FooterStyle" />
<SelectedRowStyle CssClass="SelectedRowStyle" />
</asp:GridView>
Jak ukazuje následující snímek obrazovky, tato změna zápatí jasněji vynikne.
Obrázek 12: Řádek zápatí objektu GridView má nyní červenou barvu pozadí (kliknutím zobrazíte obrázek v plné velikosti).
Krok 3: Výpočet souhrnných dat
Když se zobrazí zápatí GridView, dalším úkolem, kterému čelíme, je výpočet souhrnných dat. Tyto agregované informace můžete vypočítat dvěma způsoby:
Prostřednictvím dotazu SQL můžeme do databáze vydat další dotaz, který vypočítá souhrnná data pro určitou kategorii. SQL obsahuje řadu agregačních funkcí spolu s
GROUP BY
klauzulí k určení dat, přes která se mají data sumarizovat. Následující dotaz SQL by vrátil potřebné informace:SELECT CategoryID, AVG(UnitPrice), SUM(UnitsInStock), SUM(UnitsOnOrder) FROM Products WHERE CategoryID = categoryID GROUP BY CategoryID
Samozřejmě byste nechtěli vydat tento dotaz přímo ze
SummaryDataInFooter.aspx
stránky, ale spíše vytvořením metody v aProductsTableAdapter
.ProductsBLL
Tyto informace vypočítá, protože se přidávají do GridView, jak je popsáno v kurzu Vlastní formátování založené na datech , obslužná rutina události GridView
RowDataBound
se aktivuje jednou pro každý řádek, který se přidá do GridView po příchozích datech. Vytvořením obslužné rutiny události pro tuto událost můžeme zachovat průběžný součet hodnot, které chceme agregovat. Po vazbě posledního řádku dat k objektu GridView máme součty a informace potřebné k výpočtu průměru.
Obvykle používám druhý přístup, protože šetří cestu do databáze a úsilí potřebné k implementaci souhrnných funkcí ve vrstvě přístupu k datům a vrstvě obchodní logiky, ale jeden z přístupů by stačil. Pro účely tohoto kurzu použijeme druhou možnost a pomocí obslužné rutiny události sledujme průběžný součet RowDataBound
.
Vytvořte obslužnou rutinu RowDataBound
události pro GridView výběrem GridView v Návrháři, kliknutím na ikonu blesku z okno Vlastnosti a poklikáním RowDataBound
na událost. Tím se vytvoří nová obslužná rutina události pojmenovaná ProductsInCategory_RowDataBound
ve SummaryDataInFooter.aspx
třídě kódu stránky.
protected void ProductsInCategory_RowDataBound
(object sender, GridViewRowEventArgs e)
{
}
Abychom zachovali průběžný součet, musíme definovat proměnné mimo rozsah obslužné rutiny události. Vytvořte následující čtyři proměnné na úrovni stránky:
_totalUnitPrice
, typudecimal
_totalNonNullUnitPriceCount
, typuint
_totalUnitsInStock
, typuint
_totalUnitsOnOrder
, typuint
Dále napište kód, který zvýší tyto tři proměnné pro každý řádek dat, ke kterým došlo v obslužné rutině RowDataBound
události.
// Class-scope, running total variables...
decimal _totalUnitPrice = 0m;
int _totalNonNullUnitPriceCount = 0;
int _totalUnitsInStock = 0;
int _totalUnitsOnOrder = 0;
protected void ProductsInCategory_RowDataBound(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Reference the ProductsRow via the e.Row.DataItem property
Northwind.ProductsRow product =
(Northwind.ProductsRow)
((System.Data.DataRowView)e.Row.DataItem).Row;
// Increment the running totals (if they are not NULL!)
if (!product.IsUnitPriceNull())
{
_totalUnitPrice += product.UnitPrice;
_totalNonNullUnitPriceCount++;
}
if (!product.IsUnitsInStockNull())
_totalUnitsInStock += product.UnitsInStock;
if (!product.IsUnitsOnOrderNull())
_totalUnitsOnOrder += product.UnitsOnOrder;
}
}
Obslužná rutina RowDataBound
události začíná tím, že zajistíme, že pracujeme s DataRow. Po vytvoření je instance, Northwind.ProductsRow
která byla právě svázaná s objektem GridViewRow
, e.Row
uložena v proměnné product
. V dalším kroku se průběžné celkové proměnné zvýší o odpovídající hodnoty aktuálního produktu (za předpokladu, že neobsahují hodnotu databáze NULL
). Sledujeme průběžný UnitPrice
součet i počet záznamů,NULL
UnitPrice
protože průměrná cena je podílem těchto dvou čísel.
Krok 4: Zobrazení souhrnných dat v zápatí
S celkovým součtem souhrnných dat je posledním krokem zobrazení v řádku zápatí GridView. Tento úkol lze také provést programově prostřednictvím RowDataBound
obslužné rutiny události. Vzpomeňte si, že RowDataBound
obslužná rutina události se aktivuje pro každý řádek, který je svázaný s objektem GridView, včetně řádku zápatí. Proto můžeme naši obslužnou rutinu události rozšířit tak, aby zobrazovala data v řádku zápatí pomocí následujícího kódu:
protected void ProductsInCategory_RowDataBound
(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
... Increment the running totals ...
}
else if (e.Row.RowType == DataControlRowType.Footer)
{
... Display the summary data in the footer ...
}
}
Vzhledem k tomu, že se řádek zápatí přidá do objektu GridView po přidání všech řádků dat, můžeme si být jistí, že do doby, kdy jsme připraveni zobrazit souhrnná data v zápatí, budou dokončeny průběžné výpočty celkového součtu. Posledním krokem je nastavení těchto hodnot v buňkách zápatí.
Chcete-li zobrazit text v určité buňce zápatí, použijte e.Row.Cells[index].Text = value
, kde Cells
indexování začíná na 0. Následující kód vypočítá průměrnou cenu (celkovou cenu dělenou počtem produktů) a zobrazí ji společně s celkovým počtem jednotek v zásobách a jednotkách v příslušných buňkách zápatí gridového zobrazení.
protected void ProductsInCategory_RowDataBound
(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
... <i>Increment the running totals</i> ...
}
else if (e.Row.RowType == DataControlRowType.Footer)
{
// Determine the average UnitPrice
decimal avgUnitPrice = _totalUnitPrice / (decimal) _totalNonNullUnitPriceCount;
// Display the summary data in the appropriate cells
e.Row.Cells[1].Text = "Avg.: " + avgUnitPrice.ToString("c");
e.Row.Cells[2].Text = "Total: " + _totalUnitsInStock.ToString();
e.Row.Cells[3].Text = "Total: " + _totalUnitsOnOrder.ToString();
}
}
Obrázek 13 znázorňuje sestavu po přidání tohoto kódu. Všimněte si, ToString("c")
že příčiny formátování průměrných informací o souhrnu cen, jako je měna.
Obrázek 13: Řádek zápatí prvku GridView má nyní červenou barvu pozadí (kliknutím zobrazíte obrázek v plné velikosti).
Shrnutí
Zobrazení souhrnných dat je běžným požadavkem na sestavu a ovládací prvek GridView usnadňuje zahrnutí těchto informací do řádku zápatí. Řádek zápatí se zobrazí, když je vlastnost GridView ShowFooter
nastavena true
a může mít text v jeho buňkách nastaven programově prostřednictvím RowDataBound
obslužné rutiny události. Výpočet souhrnných dat je možné provést opětovným dotazováním databáze nebo použitím kódu v třídě kódu stránky ASP.NET za účelem programového výpočtu souhrnných dat.
V tomto kurzu se dokončí naše zkoumání vlastního formátování pomocí ovládacích prvků GridView, DetailsView a FormView. Náš další kurz zahájí zkoumání vkládání, aktualizace a odstraňování dat pomocí těchto stejných ovládacích prvků.
Šťastné programování!
O autorovi
Scott Mitchell, autor sedmi knih ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, trenér a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 za 24 hodin. Je dostupný na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím svého blogu, který lze najít na http://ScottOnWriting.NET.