DataList または Repeater コントロールのレポート データをページングする (VB)
DataList でも Repeater でも自動のページングや並べ替えはサポートされていませんが、このチュートリアルでは DataList または Repeater にページングのサポートを追加する方法を説明します。これにより、はるかに柔軟性の高いページングとデータ表示インターフェイスが可能となります。
はじめに
オンライン アプリケーションでデータを表示する場合、ページングと並べ替えは 2 つの非常に一般的な機能です。 たとえば、オンライン書店で ASP.NET に関する本を検索する場合、対象となる本は何百冊もある可能性があるとしても、検索結果リストを示すレポートには、1 ページあたり 10 件の一致データしか表示されません。 さらに、検索結果はタイトル、価格、ページ数、著者名などを基準に並べ替えることができます。 「レポート データのページングと並べ替え」のチュートリアルで説明したように、GridView、DetailsView、FormView の各コントロールはすべて、チェック ボックスにチェックを付けることで有効にできる組み込みのページング サポートを提供しています。 GridView には、並べ替えのサポートも含まれています。
残念ながら、DataList と Repeater ではどちらも、自動のページングまたは並べ替えのサポートは提供されていません。 このチュートリアルでは、DataList または Repeater にページングのサポートを追加する方法について詳しく取り上げます。 手動でページング インターフェイスを作成し、レコードの適切なページを表示し、ポストバック間でアクセスされたページを記憶する必要があります。 この場合、GridView、DetailsView、FormView を使用するよりも多くの時間とコードが必要ですが、DataList と Repeater を使用することで、はるかに柔軟性の高いページングとデータ表示インターフェイスが可能となります。
Note
このチュートリアルでは、ページングのみに焦点を当てます。 次のチュートリアルで、並べ替え機能の追加を取り上げます。
ステップ 1: ページングと並べ替えのチュートリアルの Web ページを追加する
今回のチュートリアルを開始する前に、まず、今回と次回のチュートリアルで必要になる ASP.NET ページを追加しましょう。 まず、プロジェクトに PagingSortingDataListRepeater
という名前で新しいフォルダーを作成します。 次に、以下の 5 つの ASP.NET ページをこのフォルダーに追加し、マスター ページ Site.master
を使用するようにすべてのページを構成します。
Default.aspx
Paging.aspx
Sorting.aspx
SortingWithDefaultPaging.aspx
SortingWithCustomPaging.aspx
図 1: PagingSortingDataListRepeater
フォルダーを作成し、チュートリアルの ASP.NET ページを追加する
次に、Default.aspx
ページを開き、UserControls
フォルダーの SectionLevelTutorialListing.ascx
ユーザー コントロールをデザイン画面にドラッグします。 「マスター ページとサイト ナビゲーション」のチュートリアルで作成したこのユーザー コントロールは、サイト マップを列挙し、それらのチュートリアルを現在のセクションに箇条書きリストで表示します。
図 2: SectionLevelTutorialListing.ascx
ユーザー コントロールを Default.aspx
に追加する (クリックするとフルサイズの画像が示されます)
作成するページングと並べ替えのチュートリアルを箇条書きに表示するには、それをサイト マップに追加する必要があります。 Web.sitemap
ファイルを開き、「Editing and Deleting with the DataList」のサイト マップ ノードのマークアップの後に、次のマークアップを追加します。
<siteMapNode
url="~/PagingSortingDataListRepeater/Default.aspx"
title="Paging and Sorting with the DataList and Repeater"
description="Paging and Sorting the Data in the DataList and Repeater Controls">
<siteMapNode
url="~/PagingSortingDataListRepeater/Paging.aspx"
title="Paging"
description="Learn how to page through the data shown
in the DataList and Repeater controls." />
<siteMapNode
url="~/PagingSortingDataListRepeater/Sorting.aspx"
title="Sorting"
description="Sort the data displayed in a DataList or
Repeater control." />
<siteMapNode
url="~/PagingSortingDataListRepeater/SortingWithDefaultPaging.aspx"
title="Sorting with Default Paging"
description="Create a DataList or Repeater control that is paged using
default paging and can be sorted." />
<siteMapNode
url="~/PagingSortingDataListRepeater/SortingWithCustomPaging.aspx"
title="Sorting with Custom Paging"
description="Learn how to sort the data displayed in a DataList or
Repeater control that uses custom paging." />
</siteMapNode>
図 3: 新しい ASP.NET ページが含まれるようにサイト マップを更新する
ページングのレビュー
前のチュートリアルでは、GridView、DetailsView、FormView の各コントロールでデータをページングする方法について確認しました。 この 3 つのコントロールでは、コントロールのスマート タグで [ページングを有効にする] オプションをチェックするだけで実装できる、"既定のページング" と呼ばれる単純な形式のページングが提供されます。 既定のページングでは、最初のページへのアクセス、またはユーザーが別のデータのページに移動したときに、データのページが要求されるたびに、GridView、DetailsView、FormView の各コントロールが ObjectDataSource から "すべて" のデータを再要求します。 その後、要求されたページ インデックスと、ページあたりの表示レコード数を踏まえて、表示する特定のレコード セットを切り取ります。 既定のページングについては、「レポート データのページングと並べ替え」のチュートリアルで詳しく説明しています。
既定のページングでは、ページごとにすべてのレコードが再要求されるため、大量のデータをページングする場合は実用的ではありません。 たとえば、10 件のページ サイズで 50,000 件のレコードをページングするとします。 ユーザーが新しいページに移動するたびに、50,000 件のレコードがすべてデータベースから取得されることになりますが、表示されるのは、そのうちの 10 件だけです。
"カスタム ページング" では、要求されたページに表示するレコードの正確なサブセットのみを取得することで、既定のページングのパフォーマンスに関する問題が解決されます。 カスタム ページングを実装する場合は、正確なレコード セットだけを効率的に返す SQL クエリを記述する必要があります。 そのようなクエリを SQL Server 2005 の新しい ROW_NUMBER()
keyword を使用して作成する方法については、以前に「大量のデータを効率的にページングする」のチュートリアルで確認しました。
DataList コントロールまたは Repeater コントロールに既定のページングを実装するために、PagedDataSource
class を、ページングされるコンテンツを持つ ProductsDataTable
のラッパーとして使用できます。 この PagedDataSource
クラスには、列挙可能なオブジェクトに割り当てることができる DataSource
プロパティと、ページあたりの表示レコード数と現在のページ インデックスを示す PageSize
と CurrentPageIndex
のプロパティがあります。 これらのプロパティを設定すると、PagedDataSource
を任意のデータ Web コントロールのデータ ソースとして利用できます。 列挙時に、PagedDataSource
は PageSize
と CurrentPageIndex
のプロパティに基づいて、内部の DataSource
の適切なレコードのサブセットのみを返します。 図 4 は、PagedDataSource
クラスの機能を示しています。
図 4: PagedDataSource
はページング可能なインターフェイスで列挙可能なオブジェクトをラップする
PagedDataSource
オブジェクトは、ビジネス ロジック レイヤーから直接作成し構成して、ObjectDataSource を用いて DataList または Repeater にバインドすることができます。または、ASP.NET ページの分離コード クラスで直接作成し構成することもできます。 後者の方法を使用する場合は、ObjectDataSource の使用を控え、代わりに、ページングされたデータを DataList または Repeater にプログラムによってバインドする必要があります。
PagedDataSource
オブジェクトには、カスタム ページングをサポートするプロパティもあります。 ただし、カスタム ページング向けに設計された、表示する正確なレコードを返す ProductsBLL
クラスの BLL メソッドが既に存在するため、カスタム ページングでは PagedDataSource
の使用をバイパスできます。
このチュートリアルでは、適切に構成された PagedDataSource
オブジェクトを返す ProductsBLL
クラスに新しいメソッドを追加することで、DataList に既定のページングを実装する方法について取り上げます。 次のチュートリアルでは、カスタム ページングの使用方法を確認していきます。
ステップ 2: ビジネス ロジック レイヤーに既定のページング メソッドを追加する
この ProductsBLL
クラスには現在、すべての製品情報を返すメソッド GetProducts()
と、開始インデックスで製品の特定のサブセットを返すメソッド GetProductsPaged(startRowIndex, maximumRows)
があります。 既定のページングでは、GridView、DetailsView、FormView の各コントロールはすべて、GetProducts()
メソッドを使用してすべての製品を取得しますが、内部的に PagedDataSource
を使用してレコードの正しいサブセットのみを表示します。 DataList コントロールと Repeater コントロールで、この機能を再現するには、この動作を模倣する新しいメソッドを BLL に作成します。
次の 2 つの整数入力パラメーターを受け取る GetProductsAsPagedDataSource
という名前の ProductsBLL
クラスにメソッドを追加します。
pageIndex
表示するページのインデックス、インデックス位置 0pageSize
ページあたりの表示レコード数。
GetProductsAsPagedDataSource
はまず、GetProducts()
から "すべて" のレコードを取得します。 次に、PagedDataSource
オブジェクトを作成し、その CurrentPageIndex
と PageSize
のプロパティを、渡された pageIndex
と pageSize
のパラメーターの値に設定します。 このメソッドは、次の構成の PagedDataSource
を返して終了します。
<System.ComponentModel.DataObjectMethodAttribute _
(System.ComponentModel.DataObjectMethodType.Select, False)> _
Public Function GetProductsAsPagedDataSource(ByVal pageIndex As Integer, _
ByVal pageSize As Integer) As PagedDataSource
' Get ALL of the products
Dim products As Northwind.ProductsDataTable = GetProducts()
' Limit the results through a PagedDataSource
Dim pagedData As New PagedDataSource()
pagedData.DataSource = products.Rows
pagedData.AllowPaging = True
pagedData.CurrentPageIndex = pageIndex
pagedData.PageSize = pageSize
Return pagedData
End Function
ステップ 3: 既定のページングを使用して DataList で製品情報を表示する
ProductsBLL
クラスに GetProductsAsPagedDataSource
メソッドを追加したことで、既定のページングを提供する DataList または Repeater を作成できるようになりました。 まず、PagingSortingDataListRepeater
フォルダー内のPaging.aspx
ページを開き、ツールボックスから DataList を Designer にドラッグして、DataList の ID
プロパティを ProductsDefaultPaging
に設定します。 DataList のスマート タグから、ProductsDefaultPagingDataSource
という名前で新しい ObjectDataSource を作成し、GetProductsAsPagedDataSource
メソッドを使用してデータを取得するようにそれを構成します。
図 5: ObjectDataSource を作成し、 GetProductsAsPagedDataSource
()
メソッドを使用するように構成する (フルサイズの画像を表示するには)
[UPDATE]、[INSERT]、[DELETE] の各タブのドロップダウン リストを (None) に設定します。
図 6: [UPDATE]、[INSERT]、[DELETE] の各タブのドロップダウン リストを (None) に設定する (クリックするとフルサイズの画像が表示されます)
GetProductsAsPagedDataSource
メソッドは 2 つの入力パラメーターを必要とするため、ウィザードによってこれらのパラメーター値のソースを入力するよう求められます。
ページ インデックスとページ サイズの値は、ポストバック間で記憶される必要があります。 それらはビュー状態での保存、クエリ文字列での保持、セッション変数への格納のほか、他のいくつかの手法を使用して記憶させることができます。 このチュートリアルでは、データの特定のページをブックマークできるという利点があるクエリ文字列を使用します。
具体的には、クエリ文字列フィールドの pageIndex と pageSize をそれぞれ pageIndex
と pageSize
のパラメーターに使用します (図 7 を参照)。 ユーザーがこのページに初めてアクセスするときにはクエリ文字列の値が存在しないため、これらのパラメーターの既定値の設定には少し時間がかかります。 pageIndex
の既定値を 0 (データの最初のページが表示されます) に、pageSize
の既定値を 4 に設定します。
図 7: クエリ文字列を pageIndex
と pageSize
のパラメーターのソースとして使用する (クリックするとフルサイズの画像が表示されます)
ObjectDataSource を構成すると、Visual Studio によって DataList の ItemTemplate
が自動的に作成されます。 製品名、カテゴリ、サプライヤーのみが表示されるように ItemTemplate
をカスタマイズします。 また、DataList の RepeatColumns
プロパティを 2 に、その Width
を 100% に、ItemStyle
の Width
を 50% に設定します。 これらの幅の設定により、2 つの列の間隔が等しくなります。
これらの変更を行った後の DataList と ObjectDataSource のマークアップは次のようになります。
<asp:DataList ID="ProductsDefaultPaging" runat="server" Width="100%"
DataKeyField="ProductID" DataSourceID="ProductsDefaultPagingDataSource"
RepeatColumns="2" EnableViewState="False">
<ItemTemplate>
<h4><asp:Label ID="ProductNameLabel" runat="server"
Text='<%# Eval("ProductName") %>'></asp:Label></h4>
Category:
<asp:Label ID="CategoryNameLabel" runat="server"
Text='<%# Eval("CategoryName") %>'></asp:Label><br />
Supplier:
<asp:Label ID="SupplierNameLabel" runat="server"
Text='<%# Eval("SupplierName") %>'></asp:Label><br />
<br />
<br />
</ItemTemplate>
<ItemStyle Width="50%" />
</asp:DataList>
<asp:ObjectDataSource ID="ProductsDefaultPagingDataSource" runat="server"
OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
SelectMethod="GetProductsAsPagedDataSource">
<SelectParameters>
<asp:QueryStringParameter DefaultValue="0" Name="pageIndex"
QueryStringField="pageIndex" Type="Int32" />
<asp:QueryStringParameter DefaultValue="4" Name="pageSize"
QueryStringField="pageSize" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
Note
このチュートリアルでは更新や削除の機能を実行していないため、DataList のビュー状態を無効にして、レンダリングされるページ サイズを小さくできます。
ブラウザーからこのページに最初にアクセスするときには、pageIndex
と pageSize
のクエリ文字列パラメーターはどちらも指定されません。 そのため、既定値の 0 と 4 が使用されます。 図 8 に示すように、これは、最初の 4 つの製品を表示する DataList になります。
図 8: 最初の 4 つの製品の一覧が表示される (クリックするとフルサイズの画像が表示されます)
ページング インターフェイスがないので、今のところユーザーにとって、データの 2 ページ目に移動する簡単な手段はありません。 ステップ 4 でページング インターフェイスを作成します。 現時点では、クエリ文字列でページング条件を直接指定することによってのみページングを実行できます。 たとえば、2 ページ目を表示するには、ブラウザーのアドレス バーの URL を Paging.aspx
から Paging.aspx?pageIndex=2
に変更して Enter キーを押します。 これにより、データの 2 ページ目が表示されます (図 9 を参照)。
図 9: データの 2 ページ目が表示される (クリックするとフルサイズの画像が表示されます)
ステップ 4: ページング インターフェイスを作成する
実装できるページング インターフェイスにはさまざまなものがあります。 GridView、DetailsView、FormView の各コントロールには、次の 4 つの異なるインターフェイスが用意されていて、この中から選択できます。
- [次へ]、[前へ] ユーザーは一度に 1 ページずつ、次のページか前のページに移動できます。
- [次へ]、[前へ]、[最初へ]、[最後へ][次へ] と [前へ] のボタンに加えて、このインターフェイスには、先頭ページまたは最終ページに移動するための [最初へ] と [最後へ] のボタンが含まれています。
- 数値ページング インターフェイスにページ番号が一覧表示され、ユーザーが特定のページにすばやく移動できます。
- 数値、[最初へ]、[最後へ]数値によるページ番号に加えて、先頭ページまたは最終ページに移動するためのボタンが含まれています。
DataList と Repeater の場合には、ページング インターフェイスを決定し実装する必要があります。 これには、ページに必要な Web コントロールを作成することと、特定のページング インターフェイス ボタンがクリックされたときに、要求されたページを表示することが含まれています。 さらに、特定のページング インターフェイス制御を無効にしなければならない場合があります。 たとえば、"[次へ]、[前へ]、[最初へ]、[最後へ]" のインターフェイスを使用してデータの最初のページを表示している時は、[最初へ] と [前へ] の両ボタンを無効にします。
このチュートリアルでは、"[次へ]、[前へ]、[最初へ]、[最後へ]" のインターフェイスを使用します。 4 つのボタン Web コントロールをページに追加し、その ID
を FirstPage
、PrevPage
、NextPage
、LastPage
に設定します。 Text
プロパティを << 最初へ、< 前へ、次へ >、最後へ >> に設定します。
<asp:Button runat="server" ID="FirstPage" Text="<< First" />
<asp:Button runat="server" ID="PrevPage" Text="< Prev" />
<asp:Button runat="server" ID="NextPage" Text="Next >" />
<asp:Button runat="server" ID="LastPage" Text="Last >>" />
次に、これらの各ボタンごとに Click
イベント ハンドラーを作成します。 すぐに、要求されたページを表示するために必要なコードを追加します。
ページング対象レコードの合計数を記憶する
どのページング インターフェイスを選択しても、ページング対象レコードの合計数を計算して記憶する必要があります。 合計行数によって (ページ サイズと組み合わせて)、ページングされるデータの合計ページ数が決まります。これにより、どのページング インターフェイス制御を追加または有効にするかを特定できます。 ここで構築する "[次へ]、[前へ]、[最初へ]、[最後へ]" のインターフェイスでは、ページ数を次の 2 つの状況で利用します。
- 最後のページを表示しているかどうかを判断するために。この場合、[次へ] と [最後へ] のボタンが無効になります。
- ユーザーが [最後へ] ボタンをクリックした場合、最後のページ (インデックスがページ数より 1 つ小さい) に移動する必要があります。
ページ数は、合計行数をページ サイズで割った値を切り上げた数値として計算されます。 たとえば、ページあたり 4 つのレコードとして 79 件のレコードをページングする場合、ページ数は 20 になります (79 / 4 の切り上げ)。 数値ページング インターフェイスを使用している場合は、この情報によって、表示すべき数値ページ ボタンの数がわかります。ページング インターフェイスに [次へ] または [最後へ] ボタンが含まれている場合は、ページ数は [次へ] または [最後へ] ボタンを無効にするタイミングを決定するために使用されます。
ページング インターフェイスに [最後へ] ボタンが含まれている場合は、 [最後へ] ボタンがクリックされたときに最終ページのインデックスを判断できるように、ポストバック間でページング対象レコードの合計数が記憶されていることが不可欠です。 これを容易にするために、ASP.NET ページの分離コード クラスに、その値をビュー状態に保持する TotalRowCount
プロパティを作成します。
Private Property TotalRowCount() As Integer
Get
Dim o As Object = ViewState("TotalRowCount")
If (o Is Nothing) Then
Return -1
Else
Return Convert.ToInt32(o)
End If
End Get
set(Value as Integer)
ViewState("TotalRowCount") = value
End Set
End Property
TotalRowCount
に加えて、ページ インデックス、ページ サイズ、ページ数に簡単にアクセスできるように、時間を取って、読み取り専用のページ レベルのプロパティを作成します。
Private ReadOnly Property PageIndex() As Integer
Get
If (Not String.IsNullOrEmpty(Request.QueryString("pageIndex"))) Then
Return Convert.ToInt32(Request.QueryString("pageIndex"))
Else
Return 0
End If
End Get
End Property
Private ReadOnly Property PageSize() As Integer
Get
If (Not String.IsNullOrEmpty(Request.QueryString("pageSize"))) Then
Return Convert.ToInt32(Request.QueryString("pageSize"))
Else
Return 4
End If
End Get
End Property
Private ReadOnly Property PageCount() As Integer
Get
If TotalRowCount <= 0 OrElse PageSize <= 0 Then
Return 1
Else
Return ((TotalRowCount + PageSize) - 1) / PageSize
End If
End Get
End Property
ページング対象レコードの合計数を特定する
DataList に表示されるのは一部のサブセットだけだとしても、ObjectDataSource の Select()
メソッドから返される PagedDataSource
オブジェクトには、その中に "すべて" の製品レコードが含まれています。 PagedDataSource
の Count
property は DataList に表示される項目数のみを返します。DataSourceCount
property は PagedDataSource
内の項目の合計数を返します。 したがって、ASP.NET ページの TotalRowCount
プロパティに PagedDataSource
の DataSourceCount
プロパティの値を割り当てる必要があります。
これを実現するには、ObjectDataSource の Selected
イベントのイベント ハンドラーを作成します。 Selected
イベント ハンドラーで、ObjectDataSource の Select()
メソッドの戻り値、この場合は PagedDataSource
にアクセスできます。
Protected Sub ProductsDefaultPagingDataSource_Selected(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.ObjectDataSourceStatusEventArgs) _
Handles ProductsDefaultPagingDataSource.Selected
' Reference the PagedDataSource bound to the DataList
Dim pagedData As PagedDataSource = CType(e.ReturnValue, PagedDataSource)
' Remember the total number of records being paged through across postbacks
TotalRowCount = pagedData.DataSourceCount
End Sub
データの要求されたページを表示する
ユーザーがページング インターフェイスのいずれかのボタンをクリックすると、データの要求されたページを表示する必要があります。 ページング パラメーターはクエリ文字列を使用して指定されるため、データの要求されたページを表示するには、Response.Redirect(url)
を使用して、適切なページング パラメーターを持つ Paging.aspx
ページをユーザーのブラウザーに再要求させます。 たとえば、データの 2 ページ目を表示するには、ユーザーを Paging.aspx?pageIndex=1
にリダイレクトします。
これを容易にするために、ユーザーを Paging.aspx?pageIndex=sendUserToPageIndex
にリダイレクトする RedirectUser(sendUserToPageIndex)
メソッドを作成します。 次に、4 つの Button Click
イベント ハンドラーからこのメソッドを呼び出します。 FirstPage
Click
イベント ハンドラーで、RedirectUser(0)
を呼び出して最初のページに送信します。PrevPage
Click
イベント ハンドラーでは、ページ インデックスとしてPageIndex - 1
を使用します。
Protected Sub FirstPage_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles FirstPage.Click
' Send the user to the first page
RedirectUser(0)
End Sub
Protected Sub PrevPage_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles PrevPage.Click
' Send the user to the previous page
RedirectUser(PageIndex - 1)
End Sub
Protected Sub NextPage_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles NextPage.Click
' Send the user to the next page
RedirectUser(PageIndex + 1)
End Sub
Protected Sub LastPage_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles LastPage.Click
' Send the user to the last page
RedirectUser(PageCount - 1)
End Sub
Private Sub RedirectUser(ByVal sendUserToPageIndex As Integer)
' Send the user to the requested page
Response.Redirect(String.Format("Paging.aspx?pageIndex={0}&pageSize={1}", _
sendUserToPageIndex, PageSize))
End Sub
Click
イベント ハンドラーが完了したら、ボタンをクリックして DataList のレコードをページングできます。 どうぞお試しください。
ページング インターフェイス制御を無効にする
現時点では、どのページが表示されていても、4 つのボタンはすべて有効になっています。 ただし、データの最初のページを表示している場合は [最初へ] と [前へ] のボタンを無効にし、最後のページを表示している場合は [次へ] と [最後へ] のボタンを無効にすることが必要です。 ObjectDataSource の Select()
メソッドによって返される PagedDataSource
オブジェクトには IsFirstPage
と IsLastPage
のプロパティがあり、データの最初のページまたは最後のページを表示しているかどうかを調べて判断することができます。
ObjectDataSource の Selected
イベント ハンドラーに次のコードを追加します。
' Configure the paging interface based on the data in the PagedDataSource
FirstPage.Enabled = Not pagedData.IsFirstPage
PrevPage.Enabled = Not pagedData.IsFirstPage
NextPage.Enabled = Not pagedData.IsLastPage
LastPage.Enabled = Not pagedData.IsLastPage
この追加により、最初のページを表示している時には [最初へ] と [前へ] のボタンが無効になり、最後のページを表示している時には [次へ] と [最後へ] のボタンが無効になります。
現在表示しているページと合計ページ数をユーザーに通知することで、ページング インターフェイスを完成させましょう。 Label Web コントロールをページに追加し、その ID
プロパティを CurrentPageNumber
に設定します。 ObjectDataSource の Selected イベント ハンドラーでその Text
プロパティを、現在表示されているページ (PageIndex + 1
) とページの合計数 (PageCount
) が含まれるように設定します。
' Display the current page being viewed...
CurrentPageNumber.Text = String.Format("You are viewing page {0} of {1}...", _
PageIndex + 1, PageCount)
図 10 は、最初にアクセスした時の Paging.aspx
を示しています。 クエリ文字列は空であるため、DataList はデフォルトで最初の 4 つの製品を表示します。[最初へ] と [前へ] のボタンは無効になっています。 [次へ] をクリックすると、次の 4 つのレコードが表示されます (図 11 を参照)。[最初へ] と [前へ] のボタンが有効になりました。
図 10: データの最初のページが表示されています (クリックするとフルサイズの画像が表示されます)
図 11: データの 2 ページ目が表示されています (クリックするとフルサイズの画像が表示されます)
Note
ユーザーがページごとに表示するページ数を指定できるようにすることで、ページング インターフェイスをさらに強化できます。 たとえば、DropDownList には、5、10、25、50、All などのページ サイズ オプションの一覧を追加できます。 ページ サイズを選択すると、ユーザーは Paging.aspx?pageIndex=0&pageSize=selectedPageSize
にリダイレクトされる必要があります。 この機能強化の実装については、皆さんの演習として残しておきます。
カスタム ページングを使用する
DataList では、効率的ではない既定のページング手法を使用してデータがページングされます。 大量のデータをページングする場合には、カスタム ページングを使用することが不可欠となります。 実装の詳細は若干異なりますが、DataList でカスタム ページングを実装する場合の背後にある概念は、既定のページングの場合と同じです。 カスタム ページングでは、ProductBLL
クラス の GetProductsPaged
メソッドを使用します (GetProductsAsPagedDataSource
の代わりに)。 「大量のデータを効率的にページングする」のチュートリアルで説明したように、GetProductsPaged
には開始行インデックスと返される行の最大数を渡す必要があります。 これらのパラメーターは、既定のページングで使用される pageIndex
と pageSize
のパラメーターのように、クエリ文字列を使用して保持できます。
カスタム ページングには PagedDataSource
がないため、別の手法を使用して、ページング対象レコードの合計数、およびデータの最初のページまたは最後のページを表示しているかどうかを判断する必要があります。 ProductsBLL
クラスの TotalNumberOfProducts()
メソッドは、ページングされる製品の合計数を返します。 データの最初のページが表示されているかどうかを判断するには、開始行インデックスを調べます。それが 0 の場合、最初のページが表示されています。 開始行インデックスと返される最大行数の合計が、ページング対象レコードの合計数以上の場合、最後のページが表示されています。
次のチュートリアルでは、カスタム ページングの実装について詳しく説明していきます。
まとめ
DataList コントロールと Repeater コントロールでは、GridView、DetailsView、FormView の各コントロールにみられるような、すぐに利用できるページング のサポートは提供されていませんが、このような機能はごく簡単に追加できます。 既定のページングの最も簡単な実装方法は、製品のセット全体を PagedDataSource
内にラップし、PagedDataSource
を DataList または Repeater にバインドすることです。 このチュートリアルでは、PagedDataSource
を返すように、GetProductsAsPagedDataSource
メソッドを ProductsBLL
クラスに追加しました。 この ProductsBLL
クラスには既に、カスタム ページングに必要な GetProductsPaged
と TotalNumberOfProducts
のメソッドが含まれています。
カスタム ページングで表示する正確なレコードセットを取得すること、または既定のページングで PagedDataSource
のすべてのレコードを取得することと併せて、ページング インターフェイスを手動で追加することも必要です。 このチュートリアルでは、4 つのボタン Web コントロールを持つ "[次へ]、[前へ]、[最初へ]、[最後へ]" のインターフェイスを作成しました。 また、現在のページ番号と合計ページ数を表示する Label コントロールも追加しました。
次のチュートリアルでは、DataList と Repeater に並べ替えのサポートを追加する方法を確認していきます。 また、ページングと並べ替えの両方が可能な DataList を作成する方法についても説明していきます (既定のページングとカスタム ページングを使用した例を用いて)。
プログラミングに満足!
著者について
7 冊の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジに取り組んでいます。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。
特別な感謝
このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、Liz Shulok 氏、Ken Pespisa 氏、Bernadette Leigh 氏です。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 にmitchell@4GuysFromRolla.com行をドロップしてください。