DataList または Repeater コントロールのデータを並べ替える (C#)
このチュートリアルでは、DataList と Repeater に並べ替えのサポートを含める方法と、データをページングおよび並べ替えできる DataList または Repeater を構築する方法について説明します。
はじめに
前の チュートリアル では、DataList にページング サポートを追加する方法について説明しました。 オブジェクトを返すクラス (GetProductsAsPagedDataSource
) にProductsBLL
新しいメソッドをPagedDataSource
作成しました。 DataList または Repeater にバインドすると、DataList または Repeater には、要求されたデータ ページだけが表示されます。 この手法は、組み込みの既定のページング機能を提供するために GridView、DetailsView、および FormView コントロールによって内部的に使用される手法と似ています。
GridView には、ページングのサポートに加えて、すぐに使用できる並べ替えのサポートも含まれています。 DataList と Repeater はどちらも組み込みの並べ替え機能を提供しません。ただし、並べ替え機能は少しコードで追加できます。 このチュートリアルでは、DataList と Repeater に並べ替えのサポートを含める方法と、データをページングおよび並べ替えできる DataList または Repeater を構築する方法について説明します。
並べ替えのレビュー
「 レポート データのページングと並べ替え 」のチュートリアルで説明したように、GridView コントロールは、すぐに使える並べ替えのサポートを提供します。 各 GridView フィールドには、データを並べ替えるデータ フィールドを示す が関連付けられます SortExpression
。 GridView の AllowSorting
プロパティが に true
設定されている場合、プロパティ値を持つ SortExpression
各 GridView フィールドには、そのヘッダーが LinkButton としてレンダリングされます。 ユーザーが特定の GridView フィールドのヘッダーをクリックすると、ポストバックが発生し、クリックしたフィールドの SortExpression
に従ってデータが並べ替えられます。
GridView コントロールには、データの SortExpression
並べ替えの基準となる GridView フィールドの を格納 SortExpression
する プロパティもあります。 さらに、プロパティは、 SortDirection
データを昇順または降順で並べ替えるかどうかを示します (ユーザーが特定の GridView フィールドのヘッダー リンクを 2 回連続してクリックすると、並べ替え順序が切り替えられます)。
GridView は、データ ソース コントロールにバインドされると、その SortExpression
プロパティと SortDirection
プロパティをデータ ソース コントロールに引き離します。 データ ソース コントロールは、データを取得し、指定された SortExpression
プロパティと SortDirection
プロパティに従って並べ替えます。 データを並べ替えたら、データ ソース コントロールから GridView に返されます。
DataList コントロールまたは Repeater コントロールを使用してこの機能をレプリケートするには、次の操作を行う必要があります。
- 並べ替えインターフェイスを作成する
- 並べ替えの基準となるデータ フィールドと、昇順または降順のどちらで並べ替えるかを覚えておいてください
- ObjectDataSource に、特定のデータ フィールドでデータを並べ替えるよう指示する
手順 3 と 4 では、これら 3 つのタスクに取り組みます。 その後、DataList または Repeater にページングと並べ替えの両方のサポートを含める方法について説明します。
手順 2: リピータで製品を表示する
並べ替えに関連する機能の実装について心配する前に、まず製品を Repeater コントロールに一覧表示します。 まず、フォルダー内の Sorting.aspx
ページを PagingSortingDataListRepeater
開きます。 Web ページに Repeater コントロールを追加し、そのプロパティを ID
に SortableProducts
設定します。 Repeater のスマート タグから、 という名前ProductsDataSource
の新しい ObjectDataSource を作成し、クラスの GetProducts()
メソッドからデータをProductsBLL
取得するように構成します。 [INSERT]、[UPDATE]、[DELETE] タブのドロップダウン リストから [(なし)] オプションを選択します。
図 1: ObjectDataSource を作成し、 メソッドを GetProductsAsPagedDataSource()
使用するように構成する (クリックするとフルサイズの画像が表示されます)
図 2: UPDATE タブ、INSERT タブ、DELETE タブの Drop-Down Lists を [(なし)] に設定します (フルサイズの画像を表示する場合は、ここをクリックします)
DataList とは異なり、Visual Studio では、データ ソースにバインドした後に Repeater コントロールの が自動的に作成 ItemTemplate
されることはありません。 さらに、Repeater コントロールのスマート タグに DataList の [テンプレートの編集] オプションがないため、これを ItemTemplate
宣言によって追加する必要があります。 前のチュートリアルと同じもの ItemTemplate
を使用して、製品名、仕入先、カテゴリを表示してみましょう。
を ItemTemplate
追加した後、Repeater と ObjectDataSource の宣言型マークアップは次のようになります。
<asp:Repeater ID="SortableProducts" DataSourceID="ProductsDataSource"
EnableViewState="False" runat="server">
<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>
</asp:Repeater>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
SelectMethod="GetProducts">
</asp:ObjectDataSource>
図 3 は、ブラウザーで表示された場合のこのページを示しています。
図 3: 各製品名、仕入先、およびカテゴリが表示されている (フルサイズの画像を表示する をクリックします)
手順 3: ObjectDataSource にデータの並べ替えを指示する
Repeater に表示されるデータを並べ替えるには、データの並べ替えの基準となる並べ替え式を ObjectDataSource に通知する必要があります。 ObjectDataSource がデータを取得する前に、最初にそのイベントをSelecting
発生させます。これにより、並べ替え式を指定する機会が提供されます。 イベント ハンドラーには Selecting
、 型 ObjectDataSourceSelectingEventArgs
の オブジェクトが渡されます。このオブジェクトには 型 という名前 Arguments
の DataSourceSelectArguments
プロパティがあります。 クラスはDataSourceSelectArguments
、データのコンシューマーからデータ ソース 管理にデータ関連の要求を渡すために設計されており、 プロパティがSortExpression
含まれています。
ASP.NET ページから ObjectDataSource に並べ替え情報を渡すには、イベントのイベント ハンドラーを Selecting
作成し、次のコードを使用します。
protected void ProductsDataSource_Selecting
(object sender, ObjectDataSourceSelectingEventArgs e)
{
e.Arguments.SortExpression = sortExpression;
}
sortExpression 値には、データを並べ替えるデータ フィールドの名前 (ProductName など) を割り当てる必要があります。 並べ替え方向に関連するプロパティがないため、データを降順で並べ替える場合は、文字列 DESC を sortExpression 値 (ProductName DESC など) に追加します。
sortExpression に対していくつかのハードコーディングされた値を試し、ブラウザーで結果をテストします。 図 4 に示すように、 sortExpression として ProductName DESC を使用すると、製品は名前のアルファベット順に逆順に並べ替えられます。
図 4: 製品の名前がアルファベット順に並べ替えられている (フルサイズの画像を表示する をクリックします)
手順 4: 並べ替えインターフェイスを作成し、並べ替えの式と方向を記憶する
GridView で並べ替えのサポートを有効にすると、並べ替え可能な各フィールドのヘッダー テキストが LinkButton に変換され、クリックすると、それに応じてデータが並べ替えられます。 このような並べ替えインターフェイスは、データが列にきちんとレイアウトされている GridView にとって理にかなっています。 ただし、DataList コントロールと Repeater コントロールには、別の並べ替えインターフェイスが必要です。 データの一覧 (データグリッドではなく) の一般的な並べ替えインターフェイスは、データを並べ替えることができるフィールドを提供するドロップダウン リストです。 このチュートリアルでは、このようなインターフェイスを実装してみましょう。
Repeater の上に DropDownList Web コントロールを SortableProducts
追加し、そのプロパティを ID
に SortBy
設定します。 プロパティ ウィンドウから、プロパティの省略記号をItems
クリックして ListItem コレクション エディターを表示します。 、、および SupplierName
フィールドでデータを並べ替えるには、 CategoryName
ProductName
を追加ListItem
します。 また、 を ListItem
追加して、製品の名前をアルファベット順に逆順に並べ替えます。
プロパティは任意の ListItem
Text
値 (Name など) に設定できますが Value
、プロパティはデータ フィールドの名前 (ProductName など) に設定する必要があります。 結果を降順で並べ替えるには、ProductName DESC のように、文字列 DESC をデータ フィールド名に追加します。
図 5: 並べ替え可能なデータ フィールドごとに を追加 ListItem
する
最後に、DropDownList の右側に Button Web コントロールを追加します。 その を ID
に RefreshRepeater
設定し、その Text
プロパティを Refresh に設定します。
を ListItem
作成し、[更新] ボタンを追加すると、DropDownList と Button の宣言構文は次のようになります。
<asp:DropDownList ID="SortBy" runat="server">
<asp:ListItem Value="ProductName">Name</asp:ListItem>
<asp:ListItem Value="ProductName DESC">Name (Reverse Order)
</asp:ListItem>
<asp:ListItem Value="CategoryName">Category</asp:ListItem>
<asp:ListItem Value="SupplierName">Supplier</asp:ListItem>
</asp:DropDownList>
<asp:Button runat="server" ID="RefreshRepeater" Text="Refresh" />
並べ替え DropDownList が完了したら、次に ObjectDataSource の Selecting
イベント ハンドラーを更新して、ハードコーディングされた並べ替え式ではなく、選択した SortBy``ListItem
s Value
プロパティを使用するようにする必要があります。
protected void ProductsDataSource_Selecting
(object sender, ObjectDataSourceSelectingEventArgs e)
{
// Have the ObjectDataSource sort the results by the selected
// sort expression
e.Arguments.SortExpression = SortBy.SelectedValue;
}
この時点で最初にページにアクセスすると、製品は既定で選択されているため、SortBy
ListItem
最初はデータ フィールドでProductName
並べ替えられます (図 6 を参照)。 [カテゴリ] などの別の並べ替えオプションを選択し、[更新] をクリックすると、ポストバックが発生し、カテゴリ名でデータが並べ替えられます (図 7 を参照)。
図 6: 製品は最初に名前で並べ替えられています (クリックするとフルサイズの画像が表示されます)
図 7: 製品がカテゴリ別に並べ替えられるようになりました (クリックするとフルサイズの画像が表示されます)
注意
[更新] ボタンをクリックすると、Repeater のビュー ステートが無効になっているため、データが自動的に再並べ替えられます。これにより、Repeater はポストバックごとにデータ ソースに再バインドされます。 Repeater のビュー ステートを有効のままにした場合、並べ替えドロップダウン リストを変更しても、並べ替え順序には影響しません。 これを解決するには、Refresh Button の Click
イベントのイベント ハンドラーを作成し、Repeater をデータ ソースに再バインドします (Repeater の DataBind()
メソッドを呼び出します)。
並べ替え式と方向の記憶
並べ替え不可能な関連ポストバックが発生する可能性があるページで並べ替え可能な DataList または Repeater を作成する場合、並べ替え式と方向をポストバック間で記憶することが不可欠です。 たとえば、このチュートリアルで Repeater を更新して、各製品に [削除] ボタンを追加したとします。 ユーザーが [削除] ボタンをクリックすると、選択した製品を削除し、データを Repeater に再バインドするコードが実行されます。 ポストバックの間で並べ替えの詳細が保持されない場合、画面に表示されるデータは元の並べ替え順序に戻ります。
このチュートリアルでは、DropDownList によって並べ替え式と方向がビュー ステートに暗黙的に保存されます。 たとえば、さまざまな並べ替えオプションを提供する LinkButton を使用して別の並べ替えインターフェイスを使用していた場合は、ポストバック間の並べ替え順序を覚えておく必要があります。 これを実現するには、並べ替えパラメーターをページのビュー ステートに格納するか、クエリ文字列に並べ替えパラメーターを含めるか、その他の状態の永続化手法を使用します。
このチュートリアルの今後の例では、並べ替えの詳細をページのビューステートに保持する方法について説明します。
手順 5: 既定のページングを使用する DataList に並べ替えのサポートを追加する
前の チュートリアル では、DataList を使用して既定のページングを実装する方法について説明しました。 この前の例を拡張して、ページ データを並べ替える機能を含めます。 まず、 フォルダー内の SortingWithDefaultPaging.aspx
ページと Paging.aspx
ページを PagingSortingDataListRepeater
開きます。 ページから Paging.aspx
[ソース] ボタンをクリックして、ページの宣言型マークアップを表示します。 選択したテキストをコピーし (図 8 を参照)、タグ間の の SortingWithDefaultPaging.aspx
宣言型マークアップに <asp:Content>
貼り付けます。
図 8: タグ内の宣言型マークアップを <asp:Content>
から Paging.aspx
にレプリケートします SortingWithDefaultPaging.aspx
(フルサイズの画像を表示する 場合はクリックします)
宣言型マークアップをコピーした後、ページの分離コード クラスのメソッドとプロパティを Paging.aspx
の分離コード クラスにコピーします SortingWithDefaultPaging.aspx
。 次に、ブラウザーでページを SortingWithDefaultPaging.aspx
表示します。 と同じ機能と外観 Paging.aspx
を示す必要があります。
既定のページングと並べ替え方法を含むように ProductsBLL を拡張する
前のチュートリアルでは、 オブジェクトを GetProductsAsPagedDataSource(pageIndex, pageSize)
返す メソッドを ProductsBLL
クラスに作成しました PagedDataSource
。 この PagedDataSource
オブジェクトには ( BLL s GetProducts()
メソッドを介して) すべての製品が設定されましたが、DataList にバインドされている場合は、指定された pageIndex および pageSize 入力パラメーターに対応するレコードのみが表示されました。
このチュートリアルの前半では、ObjectDataSource のイベント ハンドラーから並べ替え式を指定することで、並べ替えの Selecting
サポートを追加しました。 これは、ObjectDataSource が、 メソッドによって返される と同様 ProductsDataTable
に、並べ替え可能なオブジェクトを返すときに適切に GetProducts()
機能します。 ただし、 PagedDataSource
メソッドによって GetProductsAsPagedDataSource
返される オブジェクトは、内部データ ソースの並べ替えをサポートしていません。 代わりに、 メソッドから返された結果を に配置するGetProducts()
前にPagedDataSource
並べ替える必要があります。
これを実現するには、 クラスに新しいメソッドを ProductsBLL
作成します GetProductsSortedAsPagedDataSource(sortExpression, pageIndex, pageSize)
。 メソッドによってGetProducts()
返される をProductsDataTable
並べ替えるには、既定の の プロパティをSort
指定しますDataTableView
。
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Select, false)]
public PagedDataSource GetProductsSortedAsPagedDataSource
(string sortExpression, int pageIndex, int pageSize)
{
// Get ALL of the products
Northwind.ProductsDataTable products = GetProducts();
// Sort the products
products.DefaultView.Sort = sortExpression;
// Limit the results through a PagedDataSource
PagedDataSource pagedData = new PagedDataSource();
pagedData.DataSource = products.DefaultView;
pagedData.AllowPaging = true;
pagedData.CurrentPageIndex = pageIndex;
pagedData.PageSize = pageSize;
return pagedData;
}
メソッドは GetProductsSortedAsPagedDataSource
、前のチュートリアルで作成した GetProductsAsPagedDataSource
メソッドとは若干異なります。 特に、 GetProductsSortedAsPagedDataSource
は追加の入力パラメーターsortExpression
を受け取り、この値を Sort
の DefaultView
プロパティにProductDataTable
割り当てます。 後で数行のコードを実行するとPagedDataSource
、オブジェクトの DataSource に がProductDataTable
DefaultView
割り当てられます。
GetProductsSortedAsPagedDataSource メソッドの呼び出しと SortExpression 入力パラメーターの値の指定
メソッドが GetProductsSortedAsPagedDataSource
完了したら、次の手順では、このパラメーターの値を指定します。 の SortingWithDefaultPaging.aspx
ObjectDataSource は現在、 メソッドを呼び出 GetProductsAsPagedDataSource
すように構成されており、コレクションで指定されている 2 つの入力パラメーターを 2 つの QueryStringParameters
入力パラメーターに SelectParameters
渡します。 これら 2 つQueryStringParameters
は、メソッドの pageIndex パラメーターと pageSize パラメーターのソースGetProductsAsPagedDataSource
が querystring フィールドpageIndex
と pageSize
から取得されることを示します。
ObjectDataSource の プロパティを SelectMethod
更新して、新しい GetProductsSortedAsPagedDataSource
メソッドを呼び出すようにします。 次に、querystring フィールド から sortExpression 入力パラメーターにアクセスできるように、新しい QueryStringParameter
を追加しますsortExpression
。 s DefaultValue
を QueryStringParameter
ProductName に設定します。
これらの変更の後、ObjectDataSource の宣言型マークアップは次のようになります。
<asp:ObjectDataSource ID="ProductsDefaultPagingDataSource"
OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
SelectMethod="GetProductsSortedAsPagedDataSource"
OnSelected="ProductsDefaultPagingDataSource_Selected" runat="server">
<SelectParameters>
<asp:QueryStringParameter DefaultValue="ProductName"
Name="sortExpression" QueryStringField="sortExpression"
Type="String" />
<asp:QueryStringParameter DefaultValue="0" Name="pageIndex"
QueryStringField="pageIndex" Type="Int32" />
<asp:QueryStringParameter DefaultValue="4" Name="pageSize"
QueryStringField="pageSize" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
この時点で、ページはその結果を SortingWithDefaultPaging.aspx
製品名のアルファベット順に並べ替えます (図 9 を参照)。 これは、既定では、ProductName の値がメソッドの sortExpression パラメーターとしてGetProductsSortedAsPagedDataSource
渡されるためです。
図 9: 既定では、結果は並 ProductName
べ替えられます (フルサイズの画像を表示する場合はクリックします)
クエリ文字列フィールド (結果などSortingWithDefaultPaging.aspx?sortExpression=CategoryName
) をsortExpression
手動で追加すると、指定した sortExpression
によって並べ替えられます。 ただし、別のデータ ページに移動する場合、この sortExpression
パラメーターは querystring に含まれません。 実際に、[次へ] または [最後のページ] ボタンをクリックすると、 に Paging.aspx
戻ります。 さらに、現在、並べ替えインターフェイスはありません。 ユーザーがページングされたデータの並べ替え順序を変更できる唯一の方法は、クエリ文字列を直接操作することです。
並べ替えインターフェイスの作成
まず、 メソッドをRedirectUser
更新してユーザーを (ではなくPaging.aspx
) にSortingWithDefaultPaging.aspx
送信し、クエリ文字列に値をsortExpression
含める必要があります。 読み取り専用のページ レベルの名前付き SortExpression
プロパティも追加する必要があります。 このプロパティは、前の PageIndex
チュートリアルで作成した プロパティや プロパティと PageSize
同様に、querystring フィールドが存在する場合は値を返し、それ以外の sortExpression
場合は既定値 ( ProductName ) を返します。
現在、 メソッドは RedirectUser
、表示するページのインデックスを 1 つの入力パラメーターのみを受け入れます。 ただし、クエリ文字列で指定されたもの以外の並べ替え式を使用して、ユーザーを特定のデータ ページにリダイレクトしたい場合があります。 すぐに、このページの並べ替えインターフェイスを作成します。これには、指定した列でデータを並べ替えるための一連の Button Web コントロールが含まれます。 これらのボタンのいずれかがクリックされると、適切な並べ替え式の値を渡すユーザーをリダイレクトします。 この機能を提供するには、 メソッドの 2 つのバージョンを RedirectUser
作成します。 1 つ目は表示するページ インデックスのみを受け入れ、2 つ目はページ インデックスと並べ替え式を受け入れます。
private string SortExpression
{
get
{
if (!string.IsNullOrEmpty(Request.QueryString["sortExpression"]))
return Request.QueryString["sortExpression"];
else
return "ProductName";
}
}
private void RedirectUser(int sendUserToPageIndex)
{
// Use the SortExpression property to get the sort expression
// from the querystring
RedirectUser(sendUserToPageIndex, SortExpression);
}
private void RedirectUser(int sendUserToPageIndex, string sendUserSortingBy)
{
// Send the user to the requested page with the requested sort expression
Response.Redirect(string.Format(
"SortingWithDefaultPaging.aspx?pageIndex={0}&pageSize={1}&sortExpression={2}",
sendUserToPageIndex, PageSize, sendUserSortingBy));
}
このチュートリアルの最初の例では、DropDownList を使用して並べ替えインターフェイスを作成しました。 この例では、DataList コントロールの上に配置された 3 つのボタン Web コントロールを使用して、 で ProductName
並べ替え、1 つを に CategoryName
、もう 1 つを に使用 SupplierName
します。 3 つのボタン Web コントロールを追加し、それらのコントロールとText
プロパティをID
適切に設定します。
<p>
<asp:Button runat="server" id="SortByProductName"
Text="Sort by Product Name" />
<asp:Button runat="server" id="SortByCategoryName"
Text="Sort by Category" />
<asp:Button runat="server" id="SortBySupplierName"
Text="Sort by Supplier" />
</p>
次に Click
、それぞれのイベント ハンドラーを作成します。 イベント ハンドラーは メソッドを RedirectUser
呼び出し、適切な並べ替え式を使用してユーザーを最初のページに返す必要があります。
protected void SortByProductName_Click(object sender, EventArgs e)
{
// Sort by ProductName
RedirectUser(0, "ProductName");
}
protected void SortByCategoryName_Click(object sender, EventArgs e)
{
// Sort by CategoryName
RedirectUser(0, "CategoryName");
}
protected void SortBySupplierName_Click(object sender, EventArgs e)
{
// Sort by SupplierName
RedirectUser(0, "SupplierName");
}
最初にページにアクセスすると、データは製品名のアルファベット順に並べ替えられます (図 9 を参照)。 [次へ] ボタンをクリックしてデータの 2 ページ目に進み、[カテゴリ別に並べ替え] ボタンをクリックします。 これにより、カテゴリ名で並べ替えられたデータの最初のページに戻ります (図 10 を参照)。 同様に、[仕入先別に並べ替え] ボタンをクリックすると、データの最初のページから仕入先別にデータが並べ替えられます。 並べ替えの選択は、データのページング時に記憶されます。 図 11 は、カテゴリ別に並べ替えてからデータの 13 ページ目に進むページを示しています。
図 10: 製品はカテゴリ別に並べ替えられています (フルサイズの画像を表示する場合はクリックします)
図 11: 並べ替え式は、データをページングするときに記憶されます (フルサイズの画像を表示する をクリックします)
手順 6: リピータ内のレコードを介したカスタム ページング
DataList の例では、非効率的な既定のページング手法を使用して、手順 5 ページでデータを調べました。 十分に大量のデータをページングする場合は、カスタム ページングを使用することが不可欠です。 「大量のデータを効率的にページングする」および「カスタム ページ データの並べ替え」チュートリアルに戻り、カスタム ページングとカスタム ページングの違いを調べ、カスタム ページングとカスタム ページ データの並べ替えを利用するために BLL でメソッドを作成しました。 特に、これら 2 つの前のチュートリアルでは、次の 3 つのメソッドを ProductsBLL
クラスに追加しました。
GetProductsPaged(startRowIndex, maximumRows)
は、 startRowIndex から始まり 、maximumRows を超えないレコードの特定のサブセットを返します。GetProductsPagedAndSorted(sortExpression, startRowIndex, maximumRows)
は、指定された sortExpression 入力パラメーターで並べ替えられたレコードの特定のサブセットを返します。TotalNumberOfProducts()
は、データベース テーブル内のレコードの合計数をProducts
提供します。
これらのメソッドを使用すると、DataList コントロールまたは Repeater コントロールを使用してデータを効率的にページングおよび並べ替えることができます。 これを説明するために、まずカスタム ページングをサポートする Repeater コントロールを作成します。次に、並べ替え機能を追加します。
フォルダー内の SortingWithCustomPaging.aspx
ページを PagingSortingDataListRepeater
開き、Repeater をページに追加し、そのプロパティを ID
に Products
設定します。 Repeater のスマート タグから、 という名前 ProductsDataSource
の新しい ObjectDataSource を作成します。 クラスの GetProductsPaged
メソッドからProductsBLL
データを選択するように構成します。
図 12: クラスの GetProductsPaged
メソッドを使用ProductsBLL
するように ObjectDataSource を構成する (フルサイズの画像を表示する をクリックします)
[UPDATE]、[INSERT]、[DELETE] タブのドロップダウン リストを [(なし)] に設定し、[次へ] ボタンをクリックします。 データ ソースの構成ウィザードで、メソッドの startRowIndex および maximumRows 入力パラメーターのGetProductsPaged
ソースの入力を求めるメッセージが表示されるようになりました。 実際には、これらの入力パラメーターは無視されます。 代わりに、startRowIndex と maximumRows の値は、このチュートリアルの最初のデモで sortExpression を指定した方法と同様に、ObjectDataSource のSelecting
イベント ハンドラーの プロパティを介してArguments
渡されます。 そのため、ウィザードのパラメーター ソース ドロップダウン リストは [なし] のままにします。
図 13: [パラメーター ソース] は [なし] のままにします (フルサイズの画像を表示する場合は、ここをクリックします)
注意
ObjectDataSource の EnablePaging
プロパティを にtrue
設定しないでください。 これにより、ObjectDataSource は、独自の startRowIndex パラメーターと maximumRows パラメーターを既存のパラメーター リストに自動的に SelectMethod
含めます。 このプロパティはEnablePaging
、カスタム ページ データを GridView、DetailsView、または FormView コントロールにバインドする場合に便利です。これらのコントロールは、ObjectDataSource からの特定の動作を想定しているため、プロパティが のtrue
場合EnablePaging
にのみ使用できます。 DataList と Repeater のページング サポートを手動で追加する必要があるため、必要な機能を ASP.NET ページ内で直接ベイクするため、このプロパティ false
は (既定値) のままにしておきます。
最後に、製品の名前、カテゴリ、サプライヤーが表示されるように Repeater ItemTemplate
を定義します。 これらの変更後、Repeater と ObjectDataSource の宣言構文は次のようになります。
<asp:Repeater ID="Products" runat="server" DataSourceID="ProductsDataSource"
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>
</asp:Repeater>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProductsPaged" TypeName="ProductsBLL">
<SelectParameters>
<asp:Parameter Name="startRowIndex" Type="Int32" />
<asp:Parameter Name="maximumRows" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
少し時間を取ってブラウザーからページにアクセスし、レコードが返されていないことに注意してください。 これは、 startRowIndex パラメーター値と maximumRows パラメーター値をまだ指定していないためです。したがって、両方に対して 0 の値が渡されます。 これらの値を指定するには、ObjectDataSource の Selecting
イベントのイベント ハンドラーを作成し、プログラムによってこれらのパラメーター値をそれぞれ 0 と 5 のハードコーディングされた値に設定します。
protected void ProductsDataSource_Selecting
(object sender, ObjectDataSourceSelectingEventArgs e)
{
e.InputParameters["startRowIndex"] = 0;
e.InputParameters["maximumRows"] = 5;
}
この変更により、ブラウザーで表示されたページには、最初の 5 つの製品が表示されます。
図 14: 最初の 5 つのレコードが表示されます (フルサイズの画像を表示する場合はクリックします)
注意
図 14 に示されている製品は、効率的なカスタム ページング クエリを実行するストアド プロシージャによって結果が によって並べ替えられるため GetProductsPaged
、製品名で ProductName
並べ替えられます。
ユーザーがページをステップ実行できるようにするには、開始行インデックスと最大行を追跡し、ポストバック間でこれらの値を記憶する必要があります。 既定のページングの例では、querystring フィールドを使用してこれらの値を保持しました。このデモでは、この情報をページのビューステートに保持してみましょう。 次の 2 つのプロパティを作成します。
private int StartRowIndex
{
get
{
object o = ViewState["StartRowIndex"];
if (o == null)
return 0;
else
return (int)o;
}
set
{
ViewState["StartRowIndex"] = value;
}
}
private int MaximumRows
{
get
{
object o = ViewState["MaximumRows"];
if (o == null)
return 5;
else
return (int)o;
}
set
{
ViewState["MaximumRows"] = value;
}
}
次に、Selecting イベント ハンドラーのコードを更新して、ハードコーディングされた値 0 と 5 の代わりに プロパティと MaximumRows
プロパティを使用StartRowIndex
するようにします。
e.InputParameters["startRowIndex"] = StartRowIndex;
e.InputParameters["maximumRows"] = MaximumRows;
この時点でも、ページには最初の 5 つのレコードだけが表示されます。 ただし、これらのプロパティが設定された状態で、ページング インターフェイスを作成する準備ができました。
ページング インターフェイスの追加
既定のページングの例で使用したのと同じ First、Previous、Next、Last ページング インターフェイスを使用してみましょう。たとえば、表示されているデータのページと合計ページ数を表示する Label Web コントロールを含みます。 Repeater の下に 4 つのボタン Web コントロールとラベルを追加します。
<p>
<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 >>" />
</p>
<p>
<asp:Label runat="server" ID="CurrentPageNumber"></asp:Label>
</p>
次に、4 つのボタンのイベント ハンドラーを作成 Click
します。 これらのボタンのいずれかがクリックされると、 を更新 StartRowIndex
し、データを Repeater に再バインドする必要があります。 [最初]、[前へ]、[次へ] ボタンのコードは簡単ですが、[最後] ボタンの場合、データの最後のページの開始行インデックスを決定するにはどうすればよいですか? このインデックスを計算し、[次へ] ボタンと [最後] ボタンを有効にする必要があるかどうかを判断するには、合計でページングされているレコードの数を把握する必要があります。 これを確認するために、 クラスの メソッドTotalNumberOfProducts()
をProductsBLL
呼び出します。 メソッドの結果を返す という名前 TotalRowCount
の読み取り専用のページ レベルのプロパティを TotalNumberOfProducts()
作成しましょう。
private int TotalRowCount
{
get
{
// Return the value from the TotalNumberOfProducts() method
ProductsBLL productsAPI = new ProductsBLL();
return productsAPI.TotalNumberOfProducts();
}
}
このプロパティを使用して、最後のページの開始行インデックスを決定できるようになりました。 具体的には、負の 1 の整数の結果を TotalRowCount
で除算し MaximumRows
、 に を乗算します MaximumRows
。 4 つのページング インターフェイス ボタンのイベント ハンドラーを記述 Click
できるようになりました。
protected void FirstPage_Click(object sender, EventArgs e)
{
// Return to StartRowIndex of 0 and rebind data
StartRowIndex = 0;
Products.DataBind();
}
protected void PrevPage_Click(object sender, EventArgs e)
{
// Subtract MaximumRows from StartRowIndex and rebind data
StartRowIndex -= MaximumRows;
Products.DataBind();
}
protected void NextPage_Click(object sender, EventArgs e)
{
// Add MaximumRows to StartRowIndex and rebind data
StartRowIndex += MaximumRows;
Products.DataBind();
}
protected void LastPage_Click(object sender, EventArgs e)
{
// Set StartRowIndex = to last page's starting row index and rebind data
StartRowIndex = ((TotalRowCount - 1) / MaximumRows) * MaximumRows;
Products.DataBind();
}
最後に、データの最初のページを表示する場合はページング インターフェイスの [最初] ボタンと [前へ] ボタン、最後のページを表示する場合は [次へ] ボタンと [最後へ] ボタンを無効にする必要があります。 これを実現するには、ObjectDataSource のイベント ハンドラーに次の Selecting
コードを追加します。
// Disable the paging interface buttons, if needed
FirstPage.Enabled = StartRowIndex != 0;
PrevPage.Enabled = StartRowIndex != 0;
int LastPageStartRowIndex = ((TotalRowCount - 1) / MaximumRows) * MaximumRows;
NextPage.Enabled = StartRowIndex < LastPageStartRowIndex;
LastPage.Enabled = StartRowIndex < LastPageStartRowIndex;
これらの Click
イベント ハンドラーと、現在の開始行インデックスに基づいてページング インターフェイス要素を有効または無効にするコードを追加した後、ブラウザーでページをテストします。 図 15 に示すように、最初にページにアクセスすると、[最初] ボタンと [前へ] ボタンが無効になります。 [次へ] をクリックすると 2 ページ目のデータが表示され、[最終ページ] をクリックすると最終ページが表示されます (図 16 および図 17 を参照)。 データの最後のページを表示すると、[次へ] ボタンと [最後へ] ボタンの両方が無効になります。
図 15: 製品の最初のページを表示すると、[前] ボタンと [最後] ボタンが無効になります (フルサイズの画像を表示する場合をクリックします)
図 16: 製品の 2 番目のページが表示されます (フルサイズの画像を表示する をクリックします)
図 17: [最後] をクリックすると、データの最終ページが表示されます (クリックするとフルサイズの画像が表示されます)
手順 7: カスタム ページリピータを使用した並べ替えのサポートを含む
カスタム ページングが実装されたので、並べ替えのサポートを含める準備ができました。 クラス s GetProductsPagedAndSorted
メソッドの startRowIndex および maximumRows 入力パラメーターGetProductsPaged
は ProductsBLL
と同じですが、追加の sortExpression 入力パラメーターを使用できます。 から SortingWithCustomPaging.aspx
メソッドをGetProductsPagedAndSorted
使用するには、次の手順を実行する必要があります。
- ObjectDataSource の プロパティを
SelectMethod
からGetProductsPaged
にGetProductsPagedAndSorted
変更します。 - ObjectDataSource の
SelectParameters
コレクションに sortExpressionParameter
オブジェクトを追加します。 - ページのビューステートを通じてポストバック間でその値を保持するプライベートなページレベル
SortExpression
のプロパティを作成します。 - ObjectDataSource の
Selecting
イベント ハンドラーを更新して、ObjectDataSource の sortExpression パラメーターにページ レベルSortExpression
のプロパティの値を割り当てます。 - 並べ替えインターフェイスを作成します。
まず、ObjectDataSource の SelectMethod
プロパティを更新し、sortExpression を追加しますParameter
。 sortExpressionParameter
の Type
プロパティが に設定されていることを確認しますString
。 これらの最初の 2 つのタスクを完了すると、ObjectDataSource の宣言型マークアップは次のようになります。
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
SelectMethod="GetProductsPagedAndSorted"
OnSelecting="ProductsDataSource_Selecting">
<SelectParameters>
<asp:Parameter Name="sortExpression" Type="String" />
<asp:Parameter Name="startRowIndex" Type="Int32" />
<asp:Parameter Name="maximumRows" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
次に、状態を表示するために値をシリアル化するページ レベル SortExpression
のプロパティが必要です。 並べ替え式の値が設定されていない場合は、既定として ProductName を使用します。
private string SortExpression
{
get
{
object o = ViewState["SortExpression"];
if (o == null)
return "ProductName";
else
return o.ToString();
}
set
{
ViewState["SortExpression"] = value;
}
}
ObjectDataSource が メソッドを GetProductsPagedAndSorted
呼び出す前に、 sortExpressionParameter
を プロパティの値に設定する SortExpression
必要があります。 イベント ハンドラーで Selecting
、次のコード行を追加します。
e.InputParameters["sortExpression"] = SortExpression;
残っているのは、並べ替えインターフェイスを実装することです。 前の例で行ったように、ユーザーが製品名、カテゴリ、またはサプライヤーで結果を並べ替えることを可能にする 3 つのボタン Web コントロールを使用して、並べ替えインターフェイスを実装してみましょう。
<asp:Button runat="server" id="SortByProductName"
Text="Sort by Product Name" />
<asp:Button runat="server" id="SortByCategoryName"
Text="Sort by Category" />
<asp:Button runat="server" id="SortBySupplierName"
Text="Sort by Supplier" />
これら 3 つの Button コントロールのイベント ハンドラーを作成 Click
します。 イベント ハンドラーで、 を StartRowIndex
0 にリセットし、 を SortExpression
適切な値に設定し、データを Repeater に再バインドします。
protected void SortByProductName_Click(object sender, EventArgs e)
{
StartRowIndex = 0;
SortExpression = "ProductName";
Products.DataBind();
}
protected void SortByCategoryName_Click(object sender, EventArgs e)
{
StartRowIndex = 0;
SortExpression = "CategoryName";
Products.DataBind();
}
protected void SortBySupplierName_Click(object sender, EventArgs e)
{
StartRowIndex = 0;
SortExpression = "CompanyName";
Products.DataBind();
}
それがすべてです! カスタム ページングと並べ替えを実装するための手順は多数ありましたが、この手順は既定のページングに必要な手順とよく似ています。 図 18 は、カテゴリ別に並べ替えられたデータの最後のページを表示するときの製品を示しています。
図 18: [カテゴリ別に並べ替えられたデータの最後のページ] が表示されます (フルサイズの画像を表示する場合はクリックします)
注意
前の例では、仕入先 SupplierName による並べ替え時に、並べ替え式としてが使用されていました。 ただし、カスタム ページングの実装では、CompanyName を使用する必要があります。 これは、カスタム ページングを実装するストアド プロシージャが並べ替え式をGetProductsPagedAndSorted
キーワード (keyword)にROW_NUMBER()
渡すからです。キーワード (keyword)にはROW_NUMBER()
、エイリアスではなく実際の列名が必要です。 したがって、並べ替え式のクエリ () でSuppliers
使用される別名ではなく、SupplierName
(テーブル内SELECT
の列の名前) を使用CompanyName
する必要があります。
まとめ
DataList と Repeater はどちらも組み込みの並べ替えサポートを提供しませんが、コードとカスタム並べ替えインターフェイスを少し使用して、このような機能を追加できます。 並べ替えを実装するがページングを実装しない場合、並べ替え式は ObjectDataSource の Select
メソッドに渡されるオブジェクトを通じてDataSourceSelectArguments
指定できます。 この DataSourceSelectArguments
オブジェクトの SortExpression
プロパティは、ObjectDataSource の Selecting
イベント ハンドラーで割り当てることができます。
ページングのサポートが既に提供されている DataList または Repeater に並べ替え機能を追加するには、並べ替え式を受け入れるメソッドを含むようにビジネス ロジック レイヤーをカスタマイズするのが最も簡単な方法です。 この情報は、ObjectDataSource の SelectParameters
パラメーターを介して渡すことができます。
このチュートリアルでは、DataList コントロールと Repeater コントロールを使用したページングと並べ替えの調査を完了します。 次の最後のチュートリアルでは、項目ごとにユーザーが開始するカスタム機能を提供するために、DataList と Repeater のテンプレートに Button Web コントロールを追加する方法について説明します。
プログラミングに満足!
著者について
7 冊の ASP/ASP.NET 書籍の著者であり、 4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジと協力しています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。
特別な感謝
このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は David Suru でした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 にmitchell@4GuysFromRolla.com行をドロップしてください。
フィードバック
https://aka.ms/ContentUserFeedback。
近日公開予定: 2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub イシューを段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、以下を参照してください:フィードバックの送信と表示