以下の画像のように、ページングが有効になっている GridView の Pager 内に「総レコード数」を表示するにはどうしたらいいかということを書きます。
ListView と DataPager を利用する場合は、先の記事 ListView でページ指定 のサンプルコードのように Container.TotalRowCount で総レコード数が取得できます。(注:Container は DataPager オブジェクトを参照しています)
しかしながら、GirdView を利用した場合、ページング機能は GirdView に統合されているものを利用することになり、それから「総レコード数」を取得するプロパティなどはありません。
GridView は、データーソースコントロール(SqlDataSource または ObjectDataSource)と組み合わせて使うケースがほとんどだと思いますが、その場合はデーターソースコントロールの Selected イベントのハンドラを使って「総レコード数」を取得するのが簡単そうです。
例えば、データーソースコントロールに SqlDataSource を使う場合、その Selected イベントのハンドラの引数 SqlDataSourceStatusEventArgs クラス の AffectedRows プロパティ から総レコード数を取得できます。
取得した「総レコード数」をページャーの中に表示するには、GridView.RowDataBound イベント のハンドラでページャーの行を探して、その中に追加します。
ページャーそのものはデフォルトで(何も設定しなくても) 1 2 3 4 5 6 7 8 9 10 ... というようなクリックするとその番号のページに飛べるハイパーリンクが生成されますが、PagerSettings クラス を使うともう少し細かな設定ができます。
上の画像のページャーは、PagerSettings クラスの Mode プロパティを NumericFirstLast に、PageButtonCount プロパティを 5 に設定した場合のものです。
SqlDataSource と GridView を使った場合のサンプル(上の画像のページを表示したもの)を以下にアップしておきます。
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
int GridView3TotalCount = 0;
protected void SqlDataSource1_Selected(
object sender, SqlDataSourceStatusEventArgs e)
{
GridView3TotalCount = e.AffectedRows;
}
protected void GridView3_RowDataBound(
object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Pager)
{
Label label = new Label();
label.Text = "総レコード数: " +
GridView3TotalCount.ToString();
e.Row.Cells[0].Controls.AddAt(0, label);
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>GridView Total Records</title>
</head>
<body>
<form id="form1" runat="server">
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:Northwind %>"
SelectCommand="SELECT * FROM [Orders]"
OnSelected="SqlDataSource1_Selected">
</asp:SqlDataSource>
総レコード数: <%=GridView3TotalCount%>
<asp:GridView ID="GridView3" runat="server"
AllowPaging="True"
AutoGenerateColumns="False"
DataKeyNames="OrderID"
DataSourceID="SqlDataSource1"
OnRowDataBound="GridView3_RowDataBound">
<PagerSettings
Mode="NumericFirstLast"
PageButtonCount="5">
</PagerSettings>
<Columns>
<asp:BoundField DataField="OrderID"
HeaderText="OrderID"
InsertVisible="False"
ReadOnly="True"
SortExpression="OrderID" />
<asp:BoundField DataField="CustomerID"
HeaderText="CustomerID"
SortExpression="CustomerID" />
<asp:BoundField DataField="OrderDate"
HeaderText="OrderDate"
SortExpression="OrderDate"
DataFormatString="{0:yyyy/MM/dd}" />
<asp:BoundField DataField="Freight"
HeaderText="Freight"
SortExpression="Freight"
DataFormatString="${0:N2}" />
<asp:BoundField DataField="ShipCountry"
HeaderText="ShipCountry"
SortExpression="ShipCountry" />
</Columns>
</asp:GridView>
</form>
</body>
</html>
データーソースコントロールに ObjectDataSource を使う場合も、ObjectDataSource.Selected イベントのハンドラ で「総レコード数」を取得できます。
ObjectDataSource を使う場合、ページを切り替えるたびに全レコードを DB から再度取得するという無駄なことを避けるため、普通は、先の記事 ObjectDataSource でページング に書いてあるように、必要なレコードのみ DB から取得するクラス/メソッドを実装して、それらを ObjectDataSource で定義されているプロパティに設定することになると思います。
上に紹介した記事のサンプルコードでは、GetDataByIndex と GetNumberOfMessages の 2 つのメソッドが ObjectDataSource に設定されていますが、その両方が呼ばれ、それぞれで Selected イベントが発生します(2 回 Selected イベントが発生します)。
その際、イベントハンドラの引数 ObjectDataSourceStatusEventArgs の ReturnValue プロパティ でそれぞれのメソッドが返すオブジェクトを取得できます。
したがって、e.ReturnValue が Int32 型にキャストできれば GetNumberOfMessages が返したもの、即ち全レコード数ということになります。なので、イベントハンドラのコードを以下のようにすれば「総レコード数」を取得できます。
protected void ObjectDataSource1_Selected(object sender,
ObjectDataSourceStatusEventArgs e)
{
if (e.ReturnValue is Int32)
{
GridView3TotalCount = (Int32)e.ReturnValue;
}
}
「総レコード数」さえ取得できれば、あとは GridView と Pager の実装を SqlDataSource を使った場合と同様にして Pager に表示できます。