検索
連載

第11回 Webフォームにおけるデータ連結       Part3 DataGridコントロール連載 プログラミングASP.NET ―ASP.NETによるWebアプリケーション実践開発講座― (3/3 ページ)

DataGridコントロールは、Webページ上での一覧表示にかかる労力を大幅に削減してくる。カラムごとのソートや複数ページ表示も簡単だ。

Share
Tweet
LINE
Hatena
前のページへ |       

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>

リスト11.4 asp:DataGridのソート機能(sample13.aspx)
sample13.aspxのダウンロード(sample13.zip)


図11.3 sample13.aspxの実行結果
sample13.aspxの実行(www.iwebmethod.netのページ)

 ソートを実装するために追加したコードは、以下の4カ所である。これでカラム・ヘッダの文字列がリンク・ボタンとなり、これをクリックするとそのカラムを軸にソートが行われる。なおソートが不要なカラムには、SortExpression属性を指定する必要はない。

  1. 各カラム・コントロールにSortExpression="<ソートするフィールド名>"を追加
  2. asp:DataGridコントロールにAllowSorting="true"を追加
  3. asp:DataGridコントロールにOnSortCommandを追加して、イベント・ハンドラを登録
  4. イベント・ハンドラを以下のように追加

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>

リスト11.5 asp:DataGridコントロールのページング(sample14.aspx)
sample14.aspxのダウンロード(sample14.zip)


図11.4 sample14.aspxの実行結果
sample14.aspxの実行(www.iwebmethod.netのページ)

 ページングを実装するために追加したコードは、以下の4カ所である。これでテーブル末尾にページ移動ボタンが追加され、これをクリックするとページを前後に移動することができるようになる。

  1. asp:DataGridコントロールにAllowPaging="true"を追加
  2. asp:DataGridコントロールにOnPageIndexChangedを追加して、イベント・ハンドラを登録
  3. asp:DataGridコントロールにPageSizeを追加
  4. イベント・ハンドラを以下のように追加

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コントロールについて解説する予定だ。

「連載 プログラミングASP.NET ― ASP.NETによるWebアプリケーション実践開発講座 ― 」のインデックス

連載 プログラミングASP.NET ― ASP.NETによるWebアプリケーション実践開発講座 ― 

Copyright© Digital Advantage Corp. All Rights Reserved.

前のページへ |       
ページトップに戻る