.NET TIPS

[ASP.NET]DataGridコントロールにソート機能を追加するには?

デジタルアドバンテージ
2003/10/17

 データをグリッド形式で一覧表示するDataGridコントロールには、ヘッダー行にある列名をクリックすることにより、その列の項目でグリッド内の行をソート(並べ替え)するための機構が用意されている。

 次の画面は「TIPS:[ASP.NET]DataGridコントロールで特定のカラムのみを表示するには?」で示した2番目のサンプル・プログラム(bounddg2.aspx)をベースに、ソート機能を追加したサンプル・プログラムの実行画面である。

ソート機能を使用したサンプル・プログラム(sortdg.aspx)の実行結果

 ヘッダー行にある列名(「タイトル」と「日付」)がリンクボタン(外見はハイパーリンクであるが、機能的にはボタンの役目を果たすコントロール)になっており、それぞれをクリックすることにより、タイトルでソート、あるいは日付でソートが可能になっている(ただしこのプログラムでは昇順にのみソート可能)。

 本稿ではこのソート機能を実装するために最低限必要な手順についてまとめる。

手順1:<asp:DataGrid>タグにAllowSorting="true"属性を追加

 ソート機能を有効にするには、まずDataGridコントロールを定義している<asp:DataGrid>タグにAllowSorting="true"属性を追加する。

 カラム自動生成機能が有効な場合には、この属性の追加だけで、自動生成された列のヘッダー行にある列名がリンクボタンとなる。本稿ではカラム自動生成機能は使用しない場合(AutoGenerateColumns="false"属性を指定)について解説する。

手順2:列の定義でSortExpression属性を追加

 カラム自動生成機能を使用しない場合には、<Columns>要素により表示する列を独自に定義するが、列をソート可能にするにはその定義にSortExpression属性を追加する。この属性が追加された列は、その列名がリンクボタンとなる。

 <asp:BoundColumn>要素を使用した「連結列」を列として利用する場合のSortExpression属性の記述例は次のようになる。

  <Columns>
    <asp:BoundColumn
        SortExpression="title"
        DataField="title" HeaderText="タイトル" />
    <asp:BoundColumn
        SortExpression="pubDate"
        DataField="pubDate" HeaderText="日付" />
  </Columns>

 SortExpression属性の値は、ソートのキーとなる項目を識別するための文字列を指定する。データソースとしてデータテーブル(DataTableオブジェクト)を使用していて、かつ列を上記のように<asp:BoundColumn>要素により定義している場合には、DataField属性と同じ文字列をSortExpression属性にも設定するのが一般的だ。これについては後述する。

手順3:<asp:DataGrid>タグにOnSortCommand属性でメソッドを指定

 リンクボタンとなった列名表示部分がクリックされると、DataGridコントロールでSortCommandイベントが発生する。このイベントが発生した場合に呼び出されるイベント・ハンドラとなるメソッドを次に指定する。これはOnSortCommand属性によりメソッドの名前を指定すればよい。

 手順1のAllowSorting="true"属性と、メソッド名を指定するOnSortCommand属性を追加した<asp:DataGrid>タグの記述例は次のようになる。

  <asp:DataGrid id="MyGrid"
      AllowSorting="true"
      OnSortCommand="MyGrid_Sort"
      AutoGenerateColumns="false"
      CellPadding="4"
      runat="server" >
    ……
  </asp:DataGrid>

 ここでは「MyGrid_Sort」という名前のメソッドを指定している。どの列のリンクボタンがクリックされても、このメソッドが呼び出される。

手順4:SortCommandイベントに対応するイベント・ハンドラの記述

 OnSortCommand属性で指定するイベント・ハンドラとなるメソッドは、次のようなシグネチャを持ったメソッドでなければならない。

void MyGrid_Sort(object s, DataGridSortCommandEventArgs e) {
  ……
}

 このメソッドの第2パラメータであるDataGridSortCommandEventArgsクラス(System.Web.UI.WebControls名前空間)のオブジェクトのSortExpressionプロパティにセットされている文字列が、手順2でSortExpression属性に設定した文字列である。これによりどの列がクリックされたかを知ることができる。

 以上、ここまでがDataGridコントロールがサポートしているソートのための機能である。残念ながらDataGridコントロールは行を並べ替えてグリッド表示してくれるわけではない。このため、上記のイベント・ハンドラでは、SortExpressionプロパティにより得られた文字列を基にデータソースの要素を並べ替え、再度データ連結を実行するという処理が必要となる。

手順5:データソースの並べ替え

 データソース要素の並べ替えについては、当然ながらデータソースに指定したオブジェクトによってその方法も違ってくる。データソースがデータテーブルの場合に一般的に用いられるのは、データテーブルから「データビュー」を作成し、データビューが持つソート機能を利用する方法だ。

 データビューとはDataViewクラス(System.Data名前空間)のオブジェクトのことで、データテーブルに格納されている行データに対して、特定のフィルタ処理やソート処理を行った結果得られた行データを格納できる。

 例えばDataTableオブジェクトdtがあるとすると、それと同じ行データを参照しているデータビューは次のようにして簡単に作成することができる。

DataView dv = dt.DefaultView;

 データビュー内の行のソートも簡単で、Sortプロパティに列名を設定するだけでその列名をキーとしたソートが実行される。

dv.Sort = "title";

 手順4で示したMyGrid_Sortメソッドでは、Sortプロパティの指定は次のようにして行えばよい。

dv.Sort = e.SortExpression;

 手順2で各列のSortExpression属性にデータテーブルの列名を設定しておいた理由は、その値をそのままデータビューのSortプロパティに設定できるようにするためだ。このような作りにしておけば、クリックされた列による分岐処理が不要となる。

 DataViewオブジェクトはIEnumerableインターフェイス(System.Collections名前空間)を実装しているため、DataGridコントロールのデータソースとして指定可能だ。

MyGrid.DataSource = dv;
MyGrid.DataBind();

 データソースがデータビューであっても、<Columns>要素で指定する列の定義などはデータテーブルとまったく同様に行うことができる。

ソート機能を使用したサンプル・プログラム

 以上の手順を「TIPS:[ASP.NET]DataGridコントロールで特定のカラムのみを表示するには?」で示した2番目のサンプル・プログラム(bounddg2.aspx)に適用して作成したサンプル・プログラムは次のようになる。なお、ソートしている様子が分かりやすいように、グリッドの2列目にはRSS情報内の日付データを表示している。

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>

<html>
<head>
  <script runat="server">
    DataTable MakeDataTable() {
      DataSet ds = new DataSet();
      ds.ReadXml("http://www.buildinsider.net/rss");
      return ds.Tables["item"];
    }

    void Page_Load(object s, EventArgs e) {
      if (!IsPostBack) {
        MyGrid.DataSource = MakeDataTable();
        MyGrid.DataBind();
      }
    }

    void MyGrid_Sort(object s, DataGridSortCommandEventArgs e) {
      DataTable dt = MakeDataTable();

      DataView dv = dt.DefaultView;
      dv.Sort = e.SortExpression;

      MyGrid.DataSource = dv;
      MyGrid.DataBind();
    }
  </script>
</head>

<body>
  <form runat="server">
    <asp:DataGrid id="MyGrid"
        AllowSorting="true"
        OnSortCommand="MyGrid_Sort"
        AutoGenerateColumns="false"
        CellPadding="4"
        runat="server" >

      <HeaderStyle BackColor="#BB2255" ForeColor="white"/>
      <ItemStyle   BackColor="#FFEEEE" />
      <AlternatingItemStyle BackColor="#FFDDDD" />

      <Columns>
        <asp:BoundColumn
            SortExpression="title"
            DataField="title" HeaderText="タイトル" />
        <asp:BoundColumn
            SortExpression="pubDate"
            DataField="pubDate" HeaderText="日付" />
      </Columns>

    </asp:DataGrid>
  </form>
</body>
</html>
ソート機能を使用したC#のサンプル・プログラム(sortdg.aspx)

 このサンプル・プログラムの実行結果は本稿の冒頭で示している。End of Article

カテゴリ:Webフォーム 処理対象:DataGridコントロール
使用ライブラリ:DataGridコントロール
使用ライブラリ:DataGridSortCommandEventArgsクラス(System.Web.UI.WebControls名前空間)
使用ライブラリ:DataViewクラス(System.Data名前空間)
使用ライブラリ:IEnumerableインターフェイス(System.Collections名前空間)
関連TIPS:[ASP.NET]DataGridコントロールで特定のカラムのみを表示するには?
 
この記事と関連性の高い別の.NET TIPS
[ASP.NET]DataGridコントロールの列を実行時に表示/非表示するには?
[ASP.NET]DataGridコントロールのソートを双方向にするには?
[ASP.NET]GridViewコントロールのヘッダにソート方向を表示するには?
[ASP.NET]DataGridコントロールのヘッダーにソートされた方向を表示するには?
[ASP.NET]DataGridコントロールの列にボタンを表示するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間