Dela via


Visa sammanfattningsinformation i GridViews sidfot (VB)

av Scott Mitchell

Ladda ned PDF

Sammanfattningsinformation visas ofta längst ned i rapporten på en sammanfattningsrad. GridView-kontrollen kan innehålla en sidfotsrad i vars celler vi programmatiskt kan mata in aggregerade data. I den här handledningen ska vi se hur du visar aggregerade data i den här sidfotsraden.

Inledning

Förutom att se var och en av produkternas priser, enheter i lager, enheter på beställning och omordningsnivåer, kan en användare också vara intresserad av aggregerad information, till exempel genomsnittspriset, det totala antalet enheter i lager och så vidare. Sådan sammanfattningsinformation visas ofta längst ned i rapporten på en sammanfattningsrad. GridView-kontrollen kan innehålla en sidfotsrad i vars celler vi programmatiskt kan mata in aggregerade data.

Den här uppgiften innebär tre utmaningar:

  1. Konfigurera GridView för att visa dess sidfotsrad
  2. Fastställa sammanfattningsdata. Det är, hur beräknar vi genomsnittspriset eller summan av enheterna i lager?
  3. Infoga sammanfattningsdata i lämpliga celler i sidfotsraden

I den här handledningen ska vi se hur vi kan övervinna dessa utmaningar. Mer specifikt skapar vi en sida som visar kategorierna i en listruta med den valda kategorins produkter som visas i en GridView. GridView innehåller en sidfotsrad som visar det genomsnittliga priset och det totala antalet enheter i lager och på beställning för produkter i den kategorin.

Sammanfattningsinformation visas på rutnätsvyns sidfotsrad

Bild 1: Sammanfattningsinformation visas på rutnätsvyns sidfotsrad (klicka om du vill visa en bild i full storlek)

Den här självstudien, med dess master/detail-gränssnitt för produktkategorier, bygger på de begrepp som beskrivs i den tidigare självstudien Master/Detail Filtering With a DropDownList. Om du ännu inte har gått igenom den tidigare självstudien gör du det innan du fortsätter med den här.

Steg 1: Lägga till listrutan för Kategorier och GridView för Produkter

Innan vi börjar med att lägga till sammanfattningsinformation i GridView-sidfoten ska vi först skapa huvudrapporten/detaljrapporten. När vi har slutfört det här första steget ska vi titta på hur du tar med sammanfattningsdata.

Börja med att öppna sidan SummaryDataInFooter.aspx i CustomFormatting mappen. Lägg till en DropDownList-kontroll och ange dess ID till Categories. Klicka sedan på länken Välj datakälla från listrutans smarta tagg och välj att lägga till en ny ObjectDataSource med namnet CategoriesDataSource som anropar CategoriesBLL klassens GetCategories() metod.

Lägga till en ny ObjectDataSource med namnet CategoriesDataSource

Bild 2: Lägg till en ny ObjectDataSource med namnet CategoriesDataSource (Klicka om du vill visa en bild i full storlek)

Låt ObjectDataSource anropa metoden CategoriesBLL-klassens GetCategories()

Bild 3: Låt ObjectDataSource anropa CategoriesBLL klassens GetCategories() metod (Klicka om du vill visa en bild i full storlek)

När du har konfigurerat ObjectDataSource återvänder vi till listrutans data-källkonfigurationsguide, där vi behöver ange vilket datafältvärde som ska visas och vilket som ska motsvara värdet för listrutans ListItems. Visa fältet CategoryName och använd CategoryID som värde.

Använd fälten CategoryName och CategoryID som Text och Värde för ListItems respektive

Bild 4: Använd fälten CategoryName och CategoryID som Text och Value för ListItems respektive (Klicka för att visa bilden i full storlek)

Nu har vi en listruta (Categories) som visar kategorierna i systemet. Nu måste vi lägga till en GridView som visar de produkter som tillhör den valda kategorin. Innan vi gör det bör du dock titta närmare på kryssrutan Aktivera AutoPostBack i listrutans smarta tagg. Enligt beskrivningen i självstudien Master/Detail Filtering With a DropDownList (Huvud-/detaljfiltrering med en rullgardinslista) kommer sidan att publiceras tillbaka varje gång värdet på rullgardinslistan ändras genom att egenskapen AutoPostBack sätts till True. Detta gör att GridView uppdateras och visar dessa produkter för den nyligen valda kategorin. Om egenskapen AutoPostBack är inställd på False (standardinställningen) orsakar inte ändring av kategorin någon postback och uppdaterar därför inte de listade produkterna.

Markera kryssrutan Aktivera AutoPostBack i listrutans smarta tagg

Bild 5: Markera kryssrutan Aktivera AutoPostBack i listrutans smarta tagg (Klicka om du vill visa en bild i full storlek)

Lägg till en GridView-kontroll på sidan för att visa produkterna för den valda kategorin. Ange GridView till IDProductsInCategory och binda den till en ny ObjectDataSource med namnet ProductsInCategoryDataSource.

Lägg till en ny ObjectDataSource med namnet ProductsInCategoryDataSource

Bild 6: Lägg till ett nytt ObjectDataSource-namn ProductsInCategoryDataSource (Klicka om du vill visa en bild i full storlek)

Konfigurera ObjectDataSource så att den anropar ProductsBLL klassens GetProductsByCategoryID(categoryID) -metod.

Låt ObjectDataSource anropa metoden GetProductsByCategoryID(categoryID)

Bild 7: Låt ObjectDataSource anropa GetProductsByCategoryID(categoryID) metoden (klicka om du vill visa en bild i full storlek)

GetProductsByCategoryID(categoryID) Eftersom metoden tar in en indataparameter kan vi i det sista steget i guiden ange parametervärdets källa. För att visa de produkter som tillhör den valda kategorin måste parametern hämtas från Categories listrutan.

Skärmbild som visar fönstret Konfigurera datakälla med parametervärdet categoryID valt.

Bild 8: Hämta categoryID parametervärdet från listrutan Valda kategorier (klicka om du vill visa en bild i full storlek)

När du har slutfört guiden har GridView ett BoundField för var och en av produktegenskaperna. Nu ska vi rensa dessa BoundFields så att endast ProductName, UnitPrice, UnitsInStockoch UnitsOnOrder BoundFields visas. Lägg gärna till eventuella inställningar på fältnivå i de återstående BoundFields (till exempel formatera UnitPrice som en valuta). När du har gjort dessa ändringar bör GridViews deklarativa markering se ut ungefär så här:

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

Nu har vi en fullt fungerande huvud-/detaljrapport som visar namn, enhetspris, enheter i lager och enheter på beställning för de produkter som tillhör den valda kategorin.

Skärmbild som visar GridView-rapporten för de produkter som tillhör kategorin Drycker.

Bild 9: Hämta categoryID parametervärdet från listrutan Valda kategorier (klicka om du vill visa en bild i full storlek)

Kontrollen GridView kan visa både en rubrik- och sidfotsrad. Dessa rader visas beroende på värdena för egenskaperna ShowHeader och ShowFooter, där ShowHeader har standardvärdet True och ShowFooter har standardvärdet False. Om du vill inkludera en sidfot i GridView anger du helt enkelt dess ShowFooter egenskap till True.

Ange Egenskapen ShowFooter för GridView till True

Bild 10: Ange egenskapen för GridView ShowFooter till True (Klicka om du vill visa en bild i full storlek)

Sidfotsraden har en cell för vart och ett av fälten som definierats i GridView. Dessa celler är dock tomma som standard. Ta en stund att se våra framsteg i en webbläsare. Med egenskapen ShowFooter nu inställd på Trueinnehåller GridView en tom sidfotsrad.

GridView innehåller nu en sidfotsrad

Bild 11: GridView innehåller nu en sidfotsrad (klicka om du vill visa en bild i full storlek)

Sidfotsraden i bild 11 sticker inte ut eftersom den har en vit bakgrund. Nu ska vi skapa en CSS-klass i FooterStyle som anger en mörkröd bakgrund och sedan konfigurera Skin-filen i Styles.css temat för att tilldela den här CSS-klassen till egenskapen GridView.skin för GridView i DataWebControls.FooterStyleCssClass Om du behöver fräscha upp dina kunskaper om Skins och teman kan du gå tillbaka till självstudien "Visa data med ObjectDataSource".

Börja med att lägga till följande CSS-klass i Styles.css:

.FooterStyle
{
    background-color: #a33;
    color: White;
    text-align: right;
}

FooterStyle CSS-klassen liknar klassens stilHeaderStyle, även om bakgrundsfärgen HeaderStyleär subtilt mörkare och texten visas i ett fetstilt teckensnitt. Dessutom är texten i sidfoten högerjusterad medan rubrikens text är centrerad.

Om du sedan vill associera den här CSS-klassen med varje GridView-sidfot öppnar du filen i GridView.skin Tema och anger DataWebControls-egenskapen för FooterStyle i CssClass. Efter det här tillägget bör filens markering se ut så här:

<asp:GridView runat="server" CssClass="DataWebControlStyle">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle" />
   <HeaderStyle CssClass="HeaderStyle" />
   <FooterStyle CssClass="FooterStyle" />
   <SelectedRowStyle CssClass="SelectedRowStyle" />
</asp:GridView>

Som skärmbilden nedan visar gör den här ändringen att sidfoten sticker ut tydligare.

Skärmbild som visar sammanfattningsdata i GridViews sidfotsrad formaterad med en ny bakgrundsfärg.

Bild 12: Rutnätsvyns sidfotsrad har nu en rödaktig bakgrundsfärg (klicka om du vill visa en bild i full storlek)

Steg 3: Beräkna sammanfattningsdata

När GridView-sidfoten visas är nästa utmaning att beräkna sammanfattningsdata. Det finns två sätt att beräkna den här aggregerade informationen:

  1. Via en SQL-fråga kan vi utfärda ytterligare en fråga till databasen för att beräkna sammanfattningsdata för en viss kategori. SQL innehåller ett antal aggregerade funktioner tillsammans med en GROUP BY sats för att ange de data som data ska sammanfattas över. Följande SQL-fråga skulle få tillbaka nödvändig information:

    SELECT CategoryID, AVG(UnitPrice), SUM(UnitsInStock),
    SUM(UnitsOnOrder)
    FROM Products
    WHERE CategoryID = categoryID
    GROUP BY CategoryID
    

    Naturligtvis vill du inte utfärda den här frågan direkt från SummaryDataInFooter.aspx sidan, utan snarare genom att skapa en metod i ProductsTableAdapter och ProductsBLL.

  2. Beräkna den här informationen när den läggs till i GridView enligt beskrivningen i självstudiekursen Anpassad formatering baserat på data . GridViews RowDataBound händelsehanterare utlöses en gång för varje rad som läggs till i GridView efter att den har databunden. Genom att skapa en händelsehanterare för den här händelsen kan vi behålla en löpande summa av de värden som vi vill aggregera. När den sista dataraden har bundits till GridView har vi totalsummorna och den information som behövs för att beräkna genomsnittet.

Jag använder vanligtvis den andra metoden eftersom den sparar en resa till databasen och den ansträngning som krävs för att implementera sammanfattningsfunktionerna i dataåtkomstskiktet och affärslogikskiktet, men båda metoderna skulle räcka. I den här självstudien ska vi använda det andra alternativet och hålla reda på den löpande summan med hjälp av RowDataBound händelsehanteraren.

Skapa en RowDataBound händelsehanterare för GridView genom att välja GridView i designern, klicka på blixtikonen från fönstret Egenskaper och dubbelklicka på RowDataBound händelsen. Du kan också välja GridView och dess RowDataBound-händelse från listrutorna överst i ASP.NET kod bakom klassfilen. Då skapas en ny händelsehanterare med namnet ProductsInCategory_RowDataBound i SummaryDataInFooter.aspx sidans kod bakom-klass.

Protected Sub ProductsInCategory_RowDataBound _
    (sender As Object, e As GridViewRowEventArgs) _
        Handles ProductsInCategory.RowDataBound
End Sub

För att upprätthålla en löpande summa måste vi definiera variabler utanför händelsehanterarens omfång. Skapa följande fyra sidnivåvariabler:

  • _totalUnitPrice, av typen Decimal
  • _totalNonNullUnitPriceCount, av typen Integer
  • _totalUnitsInStock, av typen Integer
  • _totalUnitsOnOrder, av typen Integer

Skriv sedan koden för att öka dessa tre variabler för varje datarad som påträffas i RowDataBound händelsehanteraren.

Dim _totalUnitPrice As Decimal = 0
Dim _totalNonNullUnitPriceCount As Integer = 0
Dim _totalUnitsInStock As Integer = 0
Dim _totalUnitsOnOrder As Integer = 0
Protected Sub ProductsInCategory_RowDataBound _
    (sender As Object, e As GridViewRowEventArgs) _
        Handles ProductsInCategory.RowDataBound
    If e.Row.RowType = DataControlRowType.DataRow Then
        Dim product As Northwind.ProductsRow = _
            CType(CType(e.Row.DataItem, DataRowView).Row, Northwind.ProductsRow)
        If Not product.IsUnitPriceNull() Then
            _totalUnitPrice += product.UnitPrice
            _totalNonNullUnitPriceCount += 1
        End If
        If Not product.IsUnitsInStockNull() Then
            _totalUnitsInStock += product.UnitsInStock
        End If
        If Not product.IsUnitsOnOrderNull() Then
            _totalUnitsOnOrder += product.UnitsOnOrder
        End If
    ElseIf e.Row.RowType = DataControlRowType.Footer Then
        Dim avgUnitPrice As Decimal = _
            _totalUnitPrice / CType(_totalNonNullUnitPriceCount, Decimal)
        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()
    End If
End Sub

Händelsehanteraren RowDataBound börjar med att kontrollera att vi hanterar en DataRow. När det har upprättats lagras den Northwind.ProductsRow instans som just var bunden till GridViewRow objektet i e.Row i variabeln product. Därefter ökas summan av variabler med motsvarande värden för den aktuella produkten, under förutsättning att de inte innehåller ett databas NULL värde. Vi håller reda på både den löpande UnitPrice summan och antalet icke-NULLUnitPrice-poster eftersom det genomsnittliga priset är kvoten av dessa två tal.

När sammanfattningsdata summeras är det sista steget att visa dem på GridViews sidfotsrad. Den här uppgiften kan också utföras programmatiskt via RowDataBound händelsehanteraren. Kom ihåg att RowDataBound händelsehanteraren utlöses för varje rad som är bunden till GridView, inklusive sidfotsraden. Därför kan vi utöka händelsehanteraren för att visa data i sidfotsraden med hjälp av följande kod:

Protected Sub ProductsInCategory_RowDataBound _
    (sender As Object, e As GridViewRowEventArgs) _
        Handles ProductsInCategory.RowDataBound
    If e.Row.RowType = DataControlRowType.DataRow Then
      ... Increment the running totals ...
    ElseIf e.Row.RowType = DataControlRowType.Footer
      ... Display the summary data in the footer ...
    End If
End Sub

Eftersom sidfotsraden läggs till i GridView när alla datarader har lagts till kan vi vara säkra på att när vi är redo att visa sammanfattningsdata i sidfoten har de löpande totala beräkningarna slutförts. Det sista steget är sedan att ange dessa värden i sidfotens celler.

Om du vill visa text i en viss sidfotscell använder du e.Row.Cells(index).Text = value, där Cells indexeringen börjar vid 0. Följande kod beräknar genomsnittspriset (det totala priset dividerat med antalet produkter) och visar det tillsammans med det totala antalet enheter i lager och enheter i ordning i lämpliga sidfotsceller i GridView.

Protected Sub ProductsInCategory_RowDataBound _
    (sender As Object, e As GridViewRowEventArgs) _
        Handles ProductsInCategory.RowDataBound
    If e.Row.RowType = DataControlRowType.DataRow Then
      ... <i>Increment the running totals</i> ...
    ElseIf e.Row.RowType = DataControlRowType.Footer
      Dim avgUnitPrice As Decimal = _
        _totalUnitPrice / CType(_totalNonNullUnitPriceCount, Decimal)
      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()
    End If
End Sub

Bild 13 visar rapporten när den här koden har lagts till. Observera hur den genomsnittliga prissammanfattningsinformationen ToString("c") formateras som en valuta.

Skärmbild som visar sammanfattningsdata i GridViews sidfotsrad formaterad som en valuta.

Bild 13: Rutnätsvyns sidfotsrad har nu en rödaktig bakgrundsfärg (klicka om du vill visa en bild i full storlek)

Sammanfattning

Att visa sammanfattningsdata är ett vanligt rapportkrav, och GridView-kontrollen gör det enkelt att inkludera sådan information i sidfotsraden. Sidfotsraden visas när GridView-egenskapen ShowFooter är inställd på True och kan låta texten i dess celler ställas in programmatiskt via RowDataBound händelsehanteraren. Databehandling av sammanfattningsdata kan antingen göras genom att återfråga databasen eller genom att använda kod i ASP.NET-sidans kod-behind-klass för att programmatiskt beräkna sammanfattningsdata.

Den här självstudien avslutar vår undersökning av anpassad formatering med kontrollerna GridView, DetailsView och FormView. I nästa självstudie börjar vi utforska hur du infogar, uppdaterar och tar bort data med samma kontroller.

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.