DataGridのページングをカスタマイズするには
● DataGridにカスタムページング機能を付加するサンプル(主キーが連番のとき適用)

図 DataGridにカスタムページング機能を付加するサンプル(主キーが連番のとき適用)
このサンプルは、DataGridのカスタムページング機能を利用してページングしています。ユーザインタフェースは、通常のページングと同じですが高速化しています。通常のページングでは、カレントページに表示されるレコード以外の余分なレコードがデータベースから読み込まれます。このサンプルでは、カレントページに表示するレコードのみデータベースから読み込みます。なお、このサンプルで採用している手法は、主キーが連番のときのみ適用できます。
このサンプルでは、以下のノウハウを習得することができます。
▲ DataGridにカスタムページング機能を追加する方法
▲ データベースからカレントページに表示するレコードのみ抽出する方法
▲ DataGridのAllowCustomPagingプロパティの使い方
▲ DataGridのVirtualItemCountプロパティの使い方
▲ OleDbCommandのExecuteScalar()メソッドの使い方
サンプルの行48-70では、DataGridを定義しています。行50では、AllowPagingプロパティにTrueを設定してページング機能を使用するようにしています。行51では、AllowCustomPagingプロパティにTrueを設定してカスタムページング機能を使用するようにしています。AllowCustomPagingにTrueを設定したときは、DataGridのVirtualItemCountプロパティにレコード件数を設定する必要があります。カスタムページング機能を使用するときは、カレントページに表示するレコードのみデータベースから抽出することができます。行52では、PageSizeプロパティに10を設定してページ当たりの行数を10行にしています。行53では、OnPageIndexChangedイベントを登録しています。このイベントは、ページ移動ボタンをクリックしたときに発生します。
行62-64のPagerStyleでは、ページ移動ボタンの種類と表示位置を設定しています。行63では、ModeプロパティにNumericPagesを設定してページ番号でページを移動するようにしています。行64では、PositionプロパティにBottomを設定してDataGridの下端にページ移動ボタンを表示するようにしています。
行65-69の<Columns>…</Columns>では、BoundColumnで得意先テーブルの得意先IDと得意先名をバインドしています。
48: <asp:DataGrid id="dgrdCustomers"
runat="server"
50: AllowPaging="True"
51: AllowCustomPaging="True"
52: PageSize="10"
53:
OnPageIndexChanged="dgrdCustomers_PageIndexChanged"
::::
>
62: <PagerStyle
CssClass="dgrdPagerStyle"
63:
Mode="NumericPages"
64:
Position="Bottom" />
65: <Columns>
66: <asp:BoundColumn
DataField="CustomerID" HeaderText="ID" />
67: <asp:BoundColumn
DataField="CompanyName" HeaderText="得意先名"
68:
ItemStyle-Width="20em" />
69: </Columns>
70:
</asp:DataGrid>
Page_Load()イベントでは、ページが最初にロードされたとき得意先テーブルのレコード件数を取得してDataGridのVirtualItemCountプロパティに設定しています。行8-9では、OleDbConnectonのインスタンスを生成しています。引数には、Web.configに登録されているデータベース接続情報を設定しています。行10では、OleDbCommandのインスタンスを生成しています。引数には、Selectステートメントを指定しています。SelectのCount(*)関数は、レコード件数を返します。行11では、OleDbConnectionのOpen()メソッドでデータベースを開いています。行12では、OleDbCommandのExecuteScalar()メソッドでレコード件数を取得してVirtualItemCountに設定しています。行13では、OleDbConnectionのClose()メソッドでデータベースを閉じています。
行15では、Sub BindData()を呼び出して得意先テーブルからカレントページに表示するレコードを抽出して表示しています。
6: Sub Page_Load()
7: If Not IsPostBack Then
8: Dim con As New
OleDbConnection( _
9:
ConfigurationSettings.AppSettings("conStringNw"))
10: Dim cmd As OleDbCommand
= New OleDbCommand("Select Count(*) From Customers", con)
11: con.Open()
12:
dgrdCustomers.VirtualItemCount = cmd.ExecuteScalar()
13: con.Close()
14: End If
15: BindData()
16: End Sub
Sub BindData()の行19-21では、得意先テーブルからカレントページに表示するレコードを抽出するSQLを生成しています。SelectステートメントのWhere句には、パラメータ変数を指定しています。行26では、パラメータ変数@StartIndexに設定する得意先IDを計算しています。DataGridのCurrentPageIndexにPageSizeを除算するとカレントページの開始番号-1の得意先IDが取得できます。CurrentPageIndexには、0から始まるページ番号が格納されています。PageSizeには、DataGridのPageSizeプロパティに設定した行数が格納されています。行27では、開始ID-1にPageSizeを加算してカレントページの最終IDを計算しています。
行28-29では、パラメータ変数にカレントページの開始ID-1と最終IDを設定しています。たとえば、カレントページが2ページ目のときは、@StartIndex, @EndIndexには以下のような値が設定されます。
@StartIndex = 1 * 10
@EndIndex = 10 + 10
行31では、OleDbDataAdapterのFill()メソッドで以下のようなSelectステートメントを実行して、カレントページに表示するレコードを抽出してDataSetに格納します。
Select CustomerID, CompanyName From Customers
Where CustomerID > 10 And CustomerID <= 20
Order By CustomerID Asc
行32では、DataSetからDataViewを生成してDataGridのDataSourceプロパティに設定します。行33では、DataGridのDataBind()メソッドで得意先テーブルをバインドしています。
18: Sub BindData()
19: Dim strSQL As String =
"Select CustomerID, CompanyName From Customers" _
20: & " Where
CustomerID > @StartIndex And CustomerID <= @EndIndex" _
21: & " Order by
CustomerID Asc"
22: Dim con As New OleDbConnection(ConfigurationSettings.AppSettings("conStringNw"))
23: Dim da As New
OleDbDataAdapter(strSQL, con)
24: Dim ds As New DataSet()
25:
26: Dim intStartIndex as Integer =
dgrdCustomers.CurrentPageIndex * dgrdCustomers.PageSize
27: Dim intEndIndex as Integer =
intStartIndex + dgrdCustomers.PageSize
28:
da.SelectCommand.Parameters.Add("@StartIndex", intStartIndex)
29:
da.SelectCommand.Parameters.Add("@EndIndex", intEndIndex)
30:
31: da.Fill(ds)
32: dgrdCustomers.DataSource = ds.Tables(0).DefaultView
33: dgrdCustomers.DataBind()
34: End Sub
DataGridからページ番号をクリックすると、DataGridのPageIndexChangedイベントが発生します。このイベントでは、DataGridのCurrentPageIndexプロパティにNewPageIndexプロパティの値を設定してSub BindData()を呼び出します。Sub BindData()では、カレントページに表示するレコードを抽出して表示します。NewPageIndexには、ページ移動行からクリックしたページ番号が格納されています。たとえば、ページ番号2をクリックすると2が格納されます。ここで使用している計算式は、データベーステーブルの主キーが連番になっているときのみ適用できます。主キーが不連続のときのカスタムページングは、後述するサンプルで解説します。
36: Sub dgrdCustomers_PageIndexChanged(s As Object,
e As DataGridPageChangedEventArgs)
37: dgrdCustomers.CurrentPageIndex =
e.NewPageIndex
38: BindData()
39: End Sub
● DataGridにカスタムページング機能を付加するサンプル(主キーが不連続のとき適用)

図 DataGridにカスタムページング機能を付加するサンプル(主キーが不連続のとき適用)
このサンプルは、DataGridにカスタムページング機能を追加して高速化しています。データベーステーブルの主キーが連番のときのサンプルはすでに解説しました、ここでは、主キーが不連続のときのカスタムページングについて解説します。主キーが不連続のときは、ページ移動ボタンにページ番号が使用できません。ページ番号の代わりに前頁、次頁のボタンを使用します。
このサンプルでは、以下のノウハウを習得できます。
▲ 主キーが不連続のときのカスタムページング機能を追加する方法
▲ データベースから前頁に表示するレコードを抽出するSQLを生成する方法
▲ データベースから次頁に表示するレコードを抽出するSQLを生成する方法
▲ DataSetからDataTableを生成する方法
▲ DataTableの先頭レコード/最終レコードの値を取得する方法
サンプルの行78-102では、DataGridを定義しています。行81では、AllowCustomPagingプロパティにTrueを設定してカスタムページング機能を使用するようにしています。カスタムページング機能を使用するときは、DataGridのVirtualItemCountプロパティにレコード件数を設定する必要があります。行82では、PageSizeプロパティにページ当たりの行数10を設定しています。行83では、OnPageIndexChangedイベントを登録しています。このイベントは、ページ移動ボタンをクリックしたときに発生します。
行92-96のPagerStyleでは、ページ移動ボタンの種類と表示位置を設定しています。行93では、ModeプロパティにNextPrevを設定して前頁、次頁のボタンを使用するようにしています。行94-95では、ボタンに表示するテキストを設定します。ボタンには、「前頁、次頁」、「<, >」など任意の文字列を表示できます。行96では、PositionプロパティにBottomを指定してページ移動ボタンを下端に表示するようにしています。
行97-101の<Columns>…</Columns>では、BoundColumnで得意先テーブルの得意先IDと得意先名をバインドしています。
78: <asp:DataGrid id="dgrdCustomers"
runat="server"
80:
AllowPaging="True"
81: AllowCustomPaging="True"
82: PageSize="10"
83:
OnPageIndexChanged="dgrdCustomers_PageIndexChanged"
:::: >
92: <PagerStyle
CssClass="dgrdPagerStyle"
93:
Mode="NextPrev"
94: PrevPageText="前頁”
95: NextPageText="次頁”
96:
Position="Bottom" />
97: <Columns>
98: <asp:BoundColumn
DataField="CustomerID" HeaderText="ID" />
99: <asp:BoundColumn
DataField="CompanyName" HeaderText="得意先名"
100:
ItemStyle-Width="20em" />
101:
</Columns>
102: </asp:DataGrid>
Page_Load()イベントの行11-12では、LableのTextプロパティに格納されている開始IDと最終IDを変数に保存しています。Textプロパティには、文字型で格納されていますので、Int32のParse()メソッドで変換しています。Labelコントロールには、カレントページの開始IDと終了IDが保存されています。これらのLabelのVisibleプロパティには、Falseが設定さているためにブラウザには表示されません。行14では、ページが最初にロードされたとき、Sub BindData()を呼び出しています。引数には、InitLoadを指定しています。
10: Sub Page_Load()
11: mintFirstID =
Int32.Parse(lblFirstID.Text)
12: mintLastID =
Int32.Parse(lblLastID.Text)
13: If Not IsPostBack Then
14:
BindData("InitLoad")
15: End If
16: End Sub
Sub BindData()の行39-60のIf…ElseIf…Else…End Ifでは、引数で指定された値(Previous, Next, InitLoad)をチェックして対応する処理を行っています。行40-45では、引数にPreviousが指定されたときのSQLを生成しています。行48-51では、引数にNextが指定されたときのSQLを生成しています。行54-59は、引数にInitLoadが指定されたときに実行されます。行54-57では、得意先テーブルのレコード件数を取得してDataGridのVirtualItemCountプロパティに設定しています。行58-59では、InitLoadのSQLを生成しています。
InitLoadのSQL:
Select Top 10 CustomerID, CompanyName From Customers
Order By CustomerID Asc
PreviousのSQL:
Select CustomerID, CompanyName From
(Select Top 10 CustomerID, CompanyName From Customers
Where CustomerID < @FirstID
Order By CustomerID Desc) As Customer1
Order By CustomerID Asc
NextのSQL:
Select Top 10 CustomerID, CompanyName From Customers
Where CustomerID > @LastID
Order By CustomerID Asc
行61では、OleDbDataAdapterのSelectCommand.CommandTextプロパティにSQLのSelectステートメントを設定しています。行62では、OleDbDataAdapterのFill()メソッドでSelectステートメントを実行してカレントページに表示するレコードをDataSetに格納しています。行63では、DataSetから得意先テーブルのDataTableを生成しています。行64-65では、DataTableのRo
31: Sub BindData(strDirection As String)
::::
39: If strDirection = "Previous"
Then
40: strSQL = "Select
CustomerID, CompanyName" _
41: &
" From" _
42: &
" (Select top " & intPageSize.ToString() & " CustomerID,
CompanyName From Customers" _
43: &
" Where CustomerID < " & mintFirstID.ToString() _
44: & " Order by
CustomerID Desc) As Customer1" _
45: &
" Order by CustomerID Asc"
47: ElseIf strDirection =
"Next" Then
48: strSQL = "Select
top " & intPageSize.ToString() & " CustomerID,
CompanyName" _
49: &
" From Customers" _
50: &
" Where CustomerID > " & mintLastID.ToString() _
51: &
" Order by CustomerID Asc"
53: Else
54: Dim cmd As
OleDbCommand = New OleDbCommand("Select Count(*) From Customers",
con)
55: con.Open()
56:
dgrdCustomers.VirtualItemCount = cmd.ExecuteScalar()
57: con.Close()
58: strSQL = "Select
Top " & intPageSize.ToString() & " CustomerID, CompanyName
From Customers" _
59: &
" Order by CustomerID Asc"
60: End If
61: da.SelectCommand.CommandText =
strSQL
62: da.Fill(ds)
63: Dim dt As DataTable = ds.Tables(0)
64: lblFirstID.Text = dt.Ro
65: lblLastID.Text = dt.Ro
66:
67: dgrdCustomers.DataSource =
ds.Tables(0).DefaultView
68: dgrdCustomers.DataBind()
69: End Sub