以前に似たようなポスト(ObjectDataSourceを使って、GridViewにページングを実装)をしました。
今回はGridViewではなく、よりHTMLをコントロールできるListViewを使います。
説明する手順は以前とほぼ同じ。

0.今回のミソ

今回のポストのポイントは、サーバーサイドページングを実装しているところです。
ListView+DataPagerでページングを実装すると、クライアントサイドでページングを実現するため、DBアクセスとかのコストがかかります。
(1ページに10件しか表示しないのに、ページングのたびに全件とってくるとか。よくある簡単なサンプルだと。)
DACの部分で適切な範囲に対してSQLを発行して、無駄なDBアクセスを減らそう。
そこがポイントです。
このポストを読むと…

  • ちゃんと制御されたDBアクセスをする→主に、2と3のObjectDataSourceの使い方
  • ちゃんと制御されたHTMLを出力させる→5と6

が、分かると思います。

完成系はこれです。

1.GridViewとObjectDataSourceとDataPagerを配置する。

ドラッグアンドドロップで、普通に配置します。
ちなみにDataPagerはListViewの外に配置します。
対応する部分だけ抽出するとこんな感じ。
[sourcecode language=”csharp”]
<asp:ListView ID="ProductListView" runat="server" DataSourceID="ProductObjectDataSource">

</asp:ListView>

<asp:DataPager ID="ProductDataPager" …>

</asp:DataPager>

<asp:ObjectDataSource ID="ProductObjectDataSource" …>

</asp:ObjectDataSource>
[/sourcecode]

2.DACでデータとデータ件数を取得するメソッドを実装する。

例としてProductLogic.csを実装します。

[sourcecode language=”csharp”]
public int CountAllProducts() {…}

//offset:テーブル内のデータの取得位置
//limit:1ページあたりのデータ件数
public List<Product> LoadAllProductsWithPaging(int offset, int limit) {…}
[/sourcecode]

3.ObjectDataSource(以降、ODS)を編集する

ObjectDataSource(以降、ODS)の設定を行います。
データソースの構成で、ビジネスオブジェクトには「ListViewSample.Code.ProductRepository」を選び、
データメソッドのSELECTには「LoadAllProductsWithPaging」を選びます。
パラメタの設定は行いません。

続いて、GUIのプロパティにてページングのための情報を記述します。

aspxのソース表示ではこのようになります。

[sourcecode language=”csharp”]
<asp:ObjectDataSource
ID="ProductObjectDataSource"
runat="server"
EnablePaging="True"
SelectCountMethod="CountAllProducts"
SelectMethod="LoadAllProductsWithPaging"
TypeName="ListViewSample2.Code.ProductLogic"
MaximumRowsParameterName="limit"
StartRowIndexParameterName="offset">
</asp:ObjectDataSource>
[/sourcecode]

このあたりまでは、GridViewでの作成方法と何も変わりません。

4.ListViewのデータソースに前述のODSを選ぶ

データソースの選択で、上述のODSを選びます。

5.ListViewを編集する。

Productのリストを表示するために、ListViewを設定します。
ListViewはGUIの操作で、データソースに合わせたテンプレートを適用してくれます。
今回はリスト表示させるだけなので、自動で出力されたaspxうぃ手で編集して、スリムアップ。
この作業、毎回やるからめんどくさい。テンプレートを自分で作れないのかな?
[sourcecode language=”csharp”]
<asp:ListView ID="ProductListView"
runat="server"
DataSourceID="ProductObjectDataSource">
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server" class="productList">
<tr> <th>Id</th> <th>Name</th> <th>UnitCost</th> <th>Description</th> </tr>
<tr id="itemPlaceholder" runat="server"></tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="IdLabel"
runat="server" Text='<%# Eval("Id") %>’ />
</td>
<td>
<asp:Label ID="NameLabel"
runat="server" Text='<%# Eval("Name") %>’ />
</td>
<td>
<asp:Label ID="UnitCostLabel"
runat="server" Text='<%# Eval("UnitCost") %>’ />
</td>
<td>
<asp:Label ID="DescriptionLabel"
runat="server" Text='<%# Eval("Description") %>’ />
</td>
</tr>
</ItemTemplate>
<EmptyDataTemplate>
データは返されませんでした。
</EmptyDataTemplate>
</asp:ListView>
[/sourcecode]

ページングに関する設定は、DataPagerに任せます。
ここがGridViewのページングと違うところ。
ですので、ページングに関する設定は何も持たせません。

6.DataPagerを編集する。

おおざっぱなところはGUIで設定します。
1ページあたりのサイズ(PageSize)と、ページングするコントロールのID(PagedControlID)をセットします。

ソースコードは以下の通り。

[sourcecode language=”csharp”]
<asp:DataPager
ID="ProductDataPager"
runat="server"
PageSize="5"
PagedControlID="ProductListView">
<Fields>
<asp:NumericPagerField
CurrentPageLabelCssClass="this-page"
NextPageText="Next >"
PreviousPageText="< Prev." />
</Fields>
</asp:DataPager>
[/sourcecode]

Fieldsタグで、どのようにページングを表示するのかを決定しています。
「たぶん」ですけど、DataPagerのデフォルトのPageSizeは10件。
だからGUIのプロパティで10件と値が入っている場合は、
ソースコードには何も表示(反映)されません。

これでOK!!
F5で実行すると、ページングが実装されています。

7.おわりに

ややこしい。やっぱりASP.NET Webフォームはややこしい。
でも、分かってくると嫌いになれないですね。
綺麗なHTMLをはかせるには、どんなルールでaspxを書けば良いのかまだまだ修行がいりそうです。