GridView のフッターに概要情報を表示する (C#)

作成者: Scott Mitchell

PDF のダウンロード

概要情報は、多くの場合、レポートの下部にあるサマリー行に表示されます。 GridView コントロールには、プログラムによって集計データを挿入できるセルを含むフッター行を含めることができます。 このチュートリアルでは、このフッター行に集計データを表示する方法について説明します。

はじめに

ユーザーは、各製品の価格、在庫単位、注文単位、並べ替えレベルを表示するだけでなく、平均価格、在庫単位の合計数などの集計情報にも関心を持つ場合があります。 このような概要情報は、多くの場合、レポートの下部にあるサマリー行に表示されます。 GridView コントロールには、プログラムによって集計データを挿入できるセルを含むフッター行を含めることができます。

このタスクには、次の 3 つの課題があります。

  1. フッター行を表示するように GridView を構成する
  2. 概要データの決定。つまり、株価や在庫単位の合計を計算する方法は何ですか?
  3. フッター行の適切なセルにサマリー データを挿入する

このチュートリアルでは、これらの課題を克服する方法について説明します。 具体的には、選択したカテゴリの製品が GridView に表示されているドロップダウン リストにカテゴリを一覧表示するページを作成します。 GridView にはフッター行が含まれます。この行には、在庫の平均価格と合計単位数、およびそのカテゴリの製品の注文が表示されます。

概要情報が GridView のフッター行に表示される

図 1: 概要情報が GridView のフッター行に表示される (フルサイズの画像を表示する をクリックします)

このチュートリアルでは、製品のマスター/詳細インターフェイスへのカテゴリを使用して、 前の「Master/Detail Filtering With a DropDownList 」チュートリアルで説明した概念に基づいています。 前のチュートリアルをまだ実行していない場合は、このチュートリアルを続行する前に行ってください。

手順 1: カテゴリの DropDownList と Products GridView の追加

GridView のフッターに概要情報を追加する前に、まずマスター/詳細レポートを作成してみましょう。 この最初の手順を完了したら、概要データを含める方法について説明します。

まず、フォルダー内の SummaryDataInFooter.aspx ページを CustomFormatting 開きます。 DropDownList コントロールを追加し、その コントロールを IDCategories設定します。 次に、DropDownList のスマート タグから [データ ソースの選択] リンクをクリックし、クラスのメソッドを呼び出す という名前CategoriesDataSourceGetCategories()新しい ObjectDataSource をCategoriesBLL追加することを選択します。

新しい ObjectDataSource 名前付き CategoriesDataSource を追加する

図 2: 名前付きの CategoriesDataSource 新しい ObjectDataSource を追加する (フルサイズの画像を表示する 場合はクリックします)

ObjectDataSource で CategoriesBLL クラスの GetCategories() メソッドを呼び出す

図 3: ObjectDataSource でクラスのメソッドをCategoriesBLL呼び出す (クリックするとフルサイズのGetCategories()画像が表示されます)

ObjectDataSource を構成した後、このウィザードは DropDownList のデータ ソース構成ウィザードに戻ります。このウィザードから、表示するデータ フィールドの値と、DropDownList ListItem の値に対応するデータ フィールドの値を指定する必要があります。 フィールドを CategoryName 表示し、 を CategoryID 値として使用します。

ListItems のテキストと値として CategoryName フィールドと CategoryID フィールドをそれぞれ使用する

図 4: フィールドと CategoryID フィールドをそれぞれ CategoryName と としてListItemTextValue使用します (フルサイズの画像を表示するには、ここをクリックします)

この時点で、システム内のカテゴリを一覧表示する DropDownList (Categories) があります。 選択したカテゴリに属する製品を一覧表示する GridView を追加する必要があります。 ただし、その前に、DropDownList のスマート タグの [自動ポストバックを有効にする] チェック ボックスをチェックしてください。 「 Master/Detail Filtering With a DropDownList 」チュートリアルで説明したように、DropDownList の AutoPostBack プロパティをページに true 設定すると、DropDownList 値が変更されるたびにポストバックされます。 これにより、GridView が更新され、新しく選択されたカテゴリの製品が表示されます。 プロパティが AutoPostBack (既定値) に false 設定されている場合、カテゴリを変更してもポストバックは発生しないため、一覧に記載されている製品は更新されません。

DropDownList のスマート タグの [自動ポストバックを有効にする] チェック ボックスをオンにする

図 5: DropDownList のスマート タグの [自動ポストバックを有効にする] チェック ボックスをオンにする (フルサイズの画像を表示する をクリックします)

選択したカテゴリの製品を表示するために、GridView コントロールをページに追加します。 GridView ID を に ProductsInCategory 設定し、 という名前 ProductsInCategoryDataSourceの新しい ObjectDataSource にバインドします。

ProductsInCategoryDataSource という名前の新しい ObjectDataSource を追加する

図 6: 名前付きの ProductsInCategoryDataSource 新しい ObjectDataSource を追加する (フルサイズの画像を表示する 場合はクリックします)

クラスGetProductsByCategoryID(categoryID)の メソッドを呼び出すように ObjectDataSource をProductsBLL構成します。

ObjectDataSource で GetProductsByCategoryID(categoryID) メソッドを呼び出す

図 7: ObjectDataSource でメソッドを呼び出す GetProductsByCategoryID(categoryID) (クリックするとフルサイズの画像が表示されます)

メソッドは GetProductsByCategoryID(categoryID) 入力パラメーターを受け取るので、ウィザードの最後の手順でパラメーター値のソースを指定できます。 選択したカテゴリの製品を表示するには、DropDownList からパラメーターを Categories プルします。

categoryID パラメーター値が選択された [データ ソースの構成] ウィンドウを示すスクリーンショット。

図 8: 選択したカテゴリ DropDownList からパラメーター値を取得 categoryID します (クリックするとフルサイズの画像が表示されます)

ウィザードを完了すると、GridView には各製品プロパティの BoundField が含まれます。 これらの BoundFields をクリーンして、、UnitPriceUnitsInStockおよび UnitsOnOrder BoundField のみが表示されるようにProductNameしましょう。 残りの BoundFields にフィールド レベルの設定を自由に追加できます (通貨として の UnitPrice 書式設定など)。 これらの変更を行った後、GridView の宣言型マークアップは次のようになります。

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

この時点で、選択したカテゴリに属する製品の名前、単価、在庫単位、および注文単位を示す完全に機能するマスター/詳細レポートがあります。

[飲料] カテゴリに属する製品の GridView レポートを示すスクリーンショット。

図 9: 選択したカテゴリの DropDownList からパラメーター値を取得 categoryID します (クリックするとフルサイズの画像が表示されます)

GridView コントロールは、ヘッダー行とフッター行の両方を表示できます。 これらの行は、 プロパティと プロパティのShowHeader値に応じてそれぞれ表示され、ShowHeader既定値ShowFootertrueは と になりますfalseShowFooter GridView にフッターを含めるには、そのプロパティを ShowFootertrue設定するだけです。

GridView の ShowFooter プロパティを true に設定する

図 10: GridView の ShowFooter プロパティを に true 設定します (クリックするとフルサイズの画像が表示されます)

フッター行には、GridView で定義されている各フィールドのセルがあります。ただし、これらのセルは既定では空です。 ブラウザーで進行状況を確認してください。 プロパティを ShowFootertrue設定すると、GridView には空のフッター行が含まれます。

GridView にフッター行が含まれるようになりました

図 11: GridView にフッター行が含まれるようになりました (フルサイズの画像を表示する場合はクリックします)

図 11 のフッター行は白い背景を持つため、目立ちません。 では、濃い赤色の背景をFooterStyle指定する CSS クラスStyles.cssを作成し、Theme のスキン ファイルをDataWebControls構成GridView.skinして、この CSS クラスを GridView の FooterStyleCssClass プロパティに割り当ててみましょう。 スキンとテーマをブラッシュアップする必要がある場合は、 ObjectDataSource を使用したデータの表示 に関するチュートリアルを参照してください。

まず、 に次の CSS クラスを Styles.css追加します。

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

CSS クラスは FooterStyle クラスとスタイル HeaderStyle が似ていますが HeaderStyle、 の背景色は微妙に濃く、テキストは太字で表示されます。 さらに、フッター内のテキストは右揃えですが、ヘッダーのテキストは中央揃えになっています。

次に、この CSS クラスを GridView のすべてのフッターに関連付けるには、Theme でファイルをGridView.skinDataWebControls開き、 の CssClass プロパティをFooterStyle設定します。 この追加後、ファイルのマークアップは次のようになります。

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

次のスクリーン ショットに示すように、この変更によりフッターがより明確に目立ちます。

新しい背景色で書式設定された GridView のフッター行の概要データを示すスクリーンショット。

図 12: GridView のフッター行に赤みがかった背景色が表示されるようになりました (フルサイズの画像を表示する をクリックします)

手順 3: 概要データの計算

GridView のフッターが表示された状態で、次に直面する課題は、概要データを計算する方法です。 この集計情報を計算するには、次の 2 つの方法があります。

  1. SQL クエリを使用して、データベースに追加のクエリを発行して、特定のカテゴリの概要データを計算できます。 SQL には、データを集計するデータを GROUP BY 指定する句と共に、多数の集計関数が含まれています。 次の SQL クエリでは、必要な情報が返されます。

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

    もちろん、このクエリをページからSummaryDataInFooter.aspx直接発行するのではなく、 と ProductsBLLProductsTableAdapterメソッドを作成します。

  2. 「データに 基づくカスタム書式設定」 チュートリアルで説明されているように、GridView に追加されているこの情報を計算すると、GridView の RowDataBound イベント ハンドラーは、データバインド後に GridView に追加される各行に対して 1 回発生します。 このイベントのイベント ハンドラーを作成することで、集計する値の合計を実行したままにすることができます。 最後のデータ行が GridView にバインドされると、合計と平均の計算に必要な情報が得られます。

私は通常、2番目のアプローチを採用しています。これは、データベースへのトリップと、データアクセス層とビジネスロジック層に概要機能を実装するために必要な労力を節約しますが、どちらのアプローチでも十分です。 このチュートリアルでは、2 番目のオプションを使用し、イベント ハンドラーを使用して実行中の合計を RowDataBound 追跡しましょう。

RowDataBound Designerで GridView を選択し、プロパティ ウィンドウから稲妻アイコンをクリックし、イベントをダブルクリックして、GridView のイベント ハンドラーを作成しますRowDataBound。 これにより、ページの分離コード クラスに SummaryDataInFooter.aspx という名前ProductsInCategory_RowDataBoundの新しいイベント ハンドラーが作成されます。

protected void ProductsInCategory_RowDataBound
    (object sender, GridViewRowEventArgs e)
{
}

実行中の合計を維持するには、イベント ハンドラーのスコープ外の変数を定義する必要があります。 次の 4 つのページ レベル変数を作成します。

  • _totalUnitPrice型の 。 decimal
  • _totalNonNullUnitPriceCount型の 。 int
  • _totalUnitsInStock型の 。 int
  • _totalUnitsOnOrder型の 。 int

次に、イベント ハンドラーで検出されたデータ行ごとに、これら 3 つの変数をインクリメントするコードを RowDataBound 記述します。

// 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;
    }
}

イベント ハンドラーは RowDataBound 、DataRow を確実に処理することから始まります。 それが確立されると、 内の Northwind.ProductsRow オブジェクトe.RowGridViewRowバインドされたインスタンスが変数 productに格納されます。 次に、実行中の合計変数は、現在の製品の対応する値によってインクリメントされます (データベース NULL 値が含まれていない場合)。 平均価格はこれら 2 つの数値の商であるため、実行中 UnitPrice の合計と非NULLUnitPrice レコードの数の両方を追跡します。

集計された集計データを使用して、最後の手順では GridView のフッター行に表示します。 このタスクも、イベント ハンドラーを使用して RowDataBound プログラムで実行できます。 イベント ハンドラーは RowDataBound 、フッター行を含め、GridView にバインド されているすべての 行に対して発生することを思い出してください。 そのため、次のコードを使用して、フッター行にデータを表示するようにイベント ハンドラーを拡張できます。

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

すべてのデータ行が追加された後、フッター行が GridView に追加されるため、フッターにサマリー データを表示する準備ができるまでに、実行中の合計計算が完了したと確信できます。 最後の手順では、フッターのセルにこれらの値を設定します。

特定のフッター セルにテキストを表示するには、 を使用 e.Row.Cells[index].Text = valueします。ここで、インデックス作成は Cells 0 から始まります。 次のコードでは、平均価格 (合計価格を製品数で割った値) を計算し、GridView の適切なフッター セルに在庫数と注文単位数の合計と共に表示します。

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();
    }
}

図 13 は、このコードが追加された後のレポートを示しています。 によって ToString("c") 平均価格の概要情報が通貨のように書式設定される方法に注意してください。

通貨として書式設定された GridView のフッター行の概要データを示すスクリーンショット。

図 13: GridView のフッター行の背景色が赤く表示されるようになりました (フルサイズの画像を表示する をクリックします)

まとめ

概要データの表示は一般的なレポート要件であり、GridView コントロールを使用すると、そのような情報をフッター行に簡単に含めることができます。 フッター行は、GridView の ShowFooter プロパティが に設定されている場合に true 表示され、そのセル内のテキストをイベント ハンドラーを介して RowDataBound プログラムによって設定できます。 概要データの計算は、データベースの再クエリを実行するか、ASP.NET ページの分離コード クラスのコードを使用してプログラムでサマリー データを計算することによって行うことができます。

このチュートリアルでは、GridView、DetailsView、および FormView コントロールを使用したカスタム書式設定の検討を終了します。 次のチュートリアルでは、これらの同じコントロールを使用したデータの挿入、更新、削除の探索を開始します。

プログラミングに満足!

著者について

7 冊の ASP/ASP.NET 書籍の著者であり、 4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジと協力しています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。