.NET TIPS

[ASP.NET]DataGridコントロールのヘッダーにソートされた方向を表示するには?

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

 「TIPS:[ASP.NET]DataGridコントロールのソートを双方向にするには?」では、DataGridコントロールでヘッダー行の列名をクリックするたびに昇順/降順の並べ替えを交互に行うようなソート機能の実装方法について解説した。ここでは、現在ソートを行っている列とその方向が一目で分かるよう、次の画面のように列名に三角マーク(▲や▼)を表示する機能を追加してみる。

ソートされた方向を表示するサンプル・プログラム(sortmark.aspx)の実行画面
クリックした列名の右に、ソートの方向を示す三角マークが表示される。この画面は「日付」で降順にソートしたところ。

 三角マークを表示するための基本方針としては、データ連結後に、三角マークをテキストとして設定したLabelコントロールをヘッダー行内の該当するセルに追加すればよい。

ヘッダー行のセルへのアクセス

 ヘッダー行へのアクセスは、各列のデータ連結後に呼びされるItemDataBoundイベントのイベント・ハンドラで行う(このイベント・ハンドラについては「TIPS:[ASP.NET]DataGridコントロールの各セルにアクセスするには?」で解説している)。そこではまず、クリックされた列名がヘッダー行内の何番目のセルにあるのかを調べる必要がある。変数sortColumnにクリックされた列の名前が入っているとすると、このイベント・ハンドラは次のようなコードになる。

void MyGrid_ItemBound(object sender, DataGridItemEventArgs e) {
  if (e.Item.ItemType == ListItemType.Header) {
    for (int i = 0; i < MyGrid.Columns.Count; i++) {
      if (MyGrid.Columns[i].SortExpression == sortColumn) {
        // クリックされた列はi番目のセル。
      }
    }
  }
}

 DataGridオブジェクト(ここでは変数MyGrid)のColumnsプロパティは、DataGridコントロールの各列を示すDataGridColumnクラス(System.Web.UI.WebControls名前空間)のオブジェクトを保持するコレクションである。DataGridColumnオブジェクトからは、列定義時にSortExpression属性により設定された文字列をSortExpressionプロパティとして取得することができる。各列について、この値とsortColumnを比較することによりクリックされた列が何番目のセルかを知ることができる。

 セルが何番目かを調べる理由は、ヘッダー行内の各セルにアクセスするためのCellsプロパティがインデックス番号でしかアクセスできないためだ。i番目のセルがクリックされた列であるとすると、上記のコードの最も内側のif文に入るコードは次のようになる。

Label label = new Label();
label.Text = (string)ViewState[sortColumn] == "ASC"? " ▲": " ▼";
e.Item.Cells[i].Controls.Add(label);

 ここで、ViewState[sortColumn]には変数sortColumnが示す列におけるソートの方向(「ASC」あるいは「DESC」)が入っており、これは列名がクリックされたときにセットしている。

ソートされた方向を表示するサンプル・プログラム

 「TIPS:[ASP.NET]DataGridコントロールのソートを双方向にするには?」で示したサンプル・プログラム(reversedg.aspx)に、いま示したItemDataBoundイベント・ハンドラを追加したサンプル・プログラムは次のようになる。reversedg.aspxへの追加および修正点は太字で示している。

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

<html>
<head>
  <script runat="server">

    string sortColumn;

    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) {

      sortColumn = e.SortExpression;

      string curSortOrder = (string)ViewState[sortColumn];
      string newSortOrder = "";

      if (curSortOrder == null || curSortOrder == "DESC") {
        newSortOrder = "ASC";
      } else {
        newSortOrder = "DESC";
      }
      ViewState[sortColumn] = newSortOrder;

      DataTable dt = MakeDataTable();
      DataView dv = dt.DefaultView;
      dv.Sort = sortColumn + " " + newSortOrder;

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

    void MyGrid_ItemBound(object sender, DataGridItemEventArgs e) {
      if (e.Item.ItemType == ListItemType.Header) {
        for (int i = 0; i < MyGrid.Columns.Count; i++) {
          if (MyGrid.Columns[i].SortExpression == sortColumn) {
            Label label = new Label();
            label.Text = (string)ViewState[sortColumn]
                              == "ASC"? " ▲": " ▼";
            e.Item.Cells[i].Controls.Add(label);
          }
        }
      }
    }

  </script>
</head>

<body>
  <form runat="server">
    <asp:DataGrid id="MyGrid"
        AllowSorting="true"
        OnSortCommand="MyGrid_Sort"
        OnItemDataBound="MyGrid_ItemBound"
        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#のサンプル・プログラム(sortmark.aspx)

 なお、ヘッダー行にアクセスするだけなら、列名のクリック時に呼び出されるMyGrid_Sortメソッドの第2パラメータからも、DataGridItemEventArgsオブジェクトのCommandSouirceプロパティにより可能だ。しかし、そのタイミングでヘッダー行のセルにLabelコントロールを追加しても、データ連結のためのDataBindメソッド呼び出しによりヘッダー行が上書きされてしまうようで、画面にはLabelコントロールは表示されない。そのため今回ではデータ連結後にヘッダー行にアクセスしている。End of Article

カテゴリ:Webフォーム 処理対象:DataGridコントロール
使用ライブラリ:DataGridコントロール
使用ライブラリ:Labelコントロール
使用ライブラリ:DataGridColumnクラス(System.Web.UI.WebControls名前空間)
関連TIPS:[ASP.NET]DataGridコントロールのソートを双方向にするには?
関連TIPS:[ASP.NET]DataGridコントロールの各セルにアクセスするには?
 
この記事と関連性の高い別の.NET TIPS
[ASP.NET]DataGridコントロールのヘッダーを複数行にするには?
[ASP.NET]GridViewコントロールのヘッダにソート方向を表示するには?
[ASP.NET]DataGridコントロールですべての行にアクセスするには?
[ASP.NET]DataGridコントロールのヘッダーを結合するには?
[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 記事ランキング

本日 月間