第11回 Webフォームにおけるデータ連結 Part3 DataGridコントロール:連載 プログラミングASP.NET ―ASP.NETによるWebアプリケーション実践開発講座― (3/3 ページ)
DataGridコントロールは、Webページ上での一覧表示にかかる労力を大幅に削減してくる。カラムごとのソートや複数ページ表示も簡単だ。
asp:DataGridのソートとページング
asp:DataGridコントロールには、asp:DataListにない便利で強力な機能が幾つか備わっている。ここでは、ソート機能とページング機能について解説する。
■ソート機能
asp:DataGridコントロールが出力したテーブルには、ごく簡単な作業でカラムごとのソート機能を追加することができる。リスト11.3(sample12.aspx)を修正し、ソート機能を追加したコードをリスト11.4に示す。
<%@ PAGE LANGUAGE="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.IO" %>
<html>
<head>
<script runat="server">
void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
datagrid1.DataSource = CreateDataSource();
datagrid1.DataBind();
}
}
ICollection CreateDataSource() {
DirectoryInfo di = new DirectoryInfo(Server.MapPath("."));
FileInfo[] fi = di.GetFiles();
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new DataColumn("fileid", typeof(int)));
dt.Columns.Add(new DataColumn("filename", typeof(String)));
dt.Columns.Add(new DataColumn("filesize", typeof(long)));
dt.Columns.Add(new DataColumn("date", typeof(DateTime)));
for (int i = 0; i < fi.Length; i++) {
dr = dt.NewRow();
dr[0] = i;
dr[1] = fi[i].Name;
dr[2] = fi[i].Length;
dr[3] = fi[i].LastWriteTime;
dt.Rows.Add(dr);
}
DataView dv = new DataView(dt);
return dv;
}
void datagrid1_Sort(object sender, DataGridSortCommandEventArgs e) {
DataView dv = (DataView) CreateDataSource();
dv.Sort = e.SortExpression;
datagrid1.DataSource = dv;
datagrid1.DataBind();
}
</script>
</head>
<body>
<form runat="server">
<div align="center">
<asp:DataGrid id="datagrid1"
AllowSorting="true"
OnSortCommand="datagrid1_Sort"
AutoGenerateColumns="false"
runat="server">
<Columns>
<asp:BoundColumn HeaderText="ファイル名"
DataField="filename" SortExpression="filename" />
<asp:BoundColumn HeaderText="サイズ"
DataField="filesize" SortExpression="filesize" />
<asp:BoundColumn HeaderText="更新日時"
DataField="date" SortExpression="date" />
</Columns>
</asp:DataGrid>
<asp:Label id="Message" runat="server" />
</div>
</form>
</body>
</html>
sample13.aspxのダウンロード(sample13.zip)
ソートを実装するために追加したコードは、以下の4カ所である。これでカラム・ヘッダの文字列がリンク・ボタンとなり、これをクリックするとそのカラムを軸にソートが行われる。なおソートが不要なカラムには、SortExpression属性を指定する必要はない。
- 各カラム・コントロールにSortExpression="<ソートするフィールド名>"を追加
- asp:DataGridコントロールにAllowSorting="true"を追加
- asp:DataGridコントロールにOnSortCommandを追加して、イベント・ハンドラを登録
- イベント・ハンドラを以下のように追加
void datagrid1_Sort(object sender, DataGridSortCommandEventArgs e) {
DataView dv = (DataView) CreateDataSource();
dv.Sort = e.SortExpression;
// カラム・コントロールに指定したSortExpressionが格納されている
datagrid1.DataSource = dv;
datagrid1.DataBind();
}
ソートを行うイベント・ハンドラでの典型的な作業は、指定されたカラムでデータソースをソートすることである。OnSortCommandに対応するイベント・ハンドラは上記したようにイベント・パラメータとしてDataGridSortCommandEventArgsオブジェクトを受け取る。このオブジェクトのメンバであるSortExpressionプロパティには、カラム・コントロールのSortExpressionに指定した文字列が格納されているため、ソートすべきカラムを知ることができる。そこでこのサンプルでは、DataView.Sortプロパティへe.SortExpressionを代入している。DataViewクラスは非常に多機能なクラスで、Sortプロパティへフィールド名を代入すれば、それだけで指定されたフィールドでソートが行われる。こうしてソートされたDataViewオブジェクトをDataSourceプロパティに代入し、再度データ連結を行えば、ソートされた状態でテーブルが出力される。
これを見ると分かるように、実はasp:DataGridコントロールにはデータソースを並べ替える機能は含まれていない。ソート済みのデータソースをデータ連結することで、ソートを実現しているのである。従って、DataViewクラスやArrayクラスのように、データソース自体にソート機能が備わっていれば、簡単にasp:DataGridコントロールにソート機能を追加できるが、それ以外のデータソースを使うときには、データソースをソートするコードを記述しなければならない。
■ページング機能
asp:DataListに備わるもう1つの高度な機能がページングである。ページングを利用すると、データソースを一気に1つのテーブルで表示せずに、複数のページに分割して出力することが可能になる。リスト11.3(sample12.aspx)を修正して、ページング機能を追加したサンプルをリスト11.5に示す。
<%@ PAGE LANGUAGE="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.IO" %>
<html>
<head>
<script runat="server">
void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
datagrid1.DataSource = CreateDataSource();
DataBind();
}
}
ICollection CreateDataSource() {
DirectoryInfo di = new DirectoryInfo(Server.MapPath("."));
FileInfo[] fi = di.GetFiles();
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new DataColumn("fileid", typeof(int)));
dt.Columns.Add(new DataColumn("filename", typeof(String)));
dt.Columns.Add(new DataColumn("filesize", typeof(long)));
dt.Columns.Add(new DataColumn("date", typeof(DateTime)));
for (int i = 0; i < fi.Length; i++) {
dr = dt.NewRow();
dr[0] = i;
dr[1] = fi[i].Name;
dr[2] = fi[i].Length;
dr[3] = fi[i].LastWriteTime;
dt.Rows.Add(dr);
}
DataView dv = new DataView(dt);
return dv;
}
void datagrid1_PageIndexChanged(object sender, DataGridPageChangedEventArgs e) {
datagrid1.CurrentPageIndex = e.NewPageIndex;
datagrid1.DataSource = CreateDataSource();
DataBind();
}
</script>
</head>
<body>
<form runat="server">
<div align="center">
(<%# datagrid1.CurrentPageIndex + 1 %>/<%# datagrid1.PageCount %>)
<asp:DataGrid id="datagrid1"
AllowPaging="true"
AutoGenerateColumns="false"
OnPageIndexChanged="datagrid1_PageIndexChanged"
PageSize="5"
runat="server">
<Columns>
<asp:BoundColumn HeaderText="ファイル名" DataField="filename" />
<asp:BoundColumn HeaderText="サイズ" DataField="filesize" />
<asp:BoundColumn HeaderText="更新日時" DataField="date" />
</Columns>
</asp:DataGrid>
<asp:Label id="Message" runat="server" />
</div>
</form>
</body>
</html>
sample14.aspxのダウンロード(sample14.zip)
ページングを実装するために追加したコードは、以下の4カ所である。これでテーブル末尾にページ移動ボタンが追加され、これをクリックするとページを前後に移動することができるようになる。
- asp:DataGridコントロールにAllowPaging="true"を追加
- asp:DataGridコントロールにOnPageIndexChangedを追加して、イベント・ハンドラを登録
- asp:DataGridコントロールにPageSizeを追加
- イベント・ハンドラを以下のように追加
void datagrid1_PageIndexChanged(object sender, DataGridPageChangedEventArgs e) {
datagrid1.CurrentPageIndex = e.NewPageIndex;
datagrid1.DataSource = CreateDataSource();
DataBind();
}
ページ移動を処理するイベント・ハンドラでは、典型的な処理を行うだけでページングを実装することができる。このイベント・ハンドラでは、イベント・パラメータをDataGridPageChangedEventArgsオブジェクトとして受け取るので、このNewPageIndexプロパティに格納されている移動後のページをDataGrid.CurrentPageIndexプロパティに代入すればよい。このようにページはasp:DataGridコントロールが管理してくれるため、基本的な機能を実装するだけならば、イベント・ハンドラで処理すべき作業はほとんどない。
なおリスト11.5では、asp:DataGridコントロールの前に以下のコードを追加して、現在のページと総ページ数を表示している。
(<%# datagrid1.CurrentPageIndex + 1 %>/<%# datagrid1.PageCount %>)
解説するまでもないが、DataGrid.CurrentPageIndexには現在指定されているページが、DataGrid.PageCountにはDataGrid.PageSizeに指定されたページサイズ(1ページに表示される要素数)での総ページ数が格納されている。
ところで、リスト11.5を最初に実行したとき、datagrid1.PageCountのデータ連結結果が「0」と表示されてしまっていることに気が付かれただろうか。これはPageCountの計算が恐らくデータ連結後に行われるためだ。このため、正しく出力するには例えば次のように修正し、データ連結後に「pagecount.Text = datagrid1.PageCount;」を実行する必要がある。
(<%# datagrid.CurrentPageIndex + 1 %>
/<asp:Label id="pagecount" runat="server" />)
次回は、asp:DataGridコントロールにおける編集モードと、データリスト・コントロールの最後の1つであるasp:Repeaterコントロールについて解説する予定だ。
Copyright© Digital Advantage Corp. All Rights Reserved.