ASP.NET 徹底活用術のホームへ戻る

DataGridの列を昇順/降順の双方向に並べ替える ~dg2.aspx

 

DataGridの並べ替え機能をカスタマイズして、ヘッダーの列見出しをクリックしたときに「昇順」および「降順」に自動的に切り替えします。また、ヘッダーの列見出しの右側に昇順のときは「▼」、降順のときは「▲」の矢印を表示します。

 

列を昇順/降順に切り替えるには、カレントの状態を保持する必要がありますので、ページクラスに「SortExpression」と「SortOrder」のプロパティを追加します。SortExpressには並べ替えするフィールド、SortOrderには並べ替え順「ASC/DESC」を保存します。Webページがポストバックされても、失われないようにこれらのプロパティの値は、ビューステート(ViewState)に保存しておきます。

 

リスト3:ページクラスにSortExpression/SortOrderのプロパティを追加(dg2.aspx.vb)

Private Property SortExpression() As String

  Get

    Dim o As Object = ViewState("SortExpression")

    If o Is Nothing Then

      Return String.Empty

    Else

      Return o.ToString

    End If

  End Get

  Set(ByVal Value As String)

    ViewState("SortExpression") = Value

  End Set

End Property

 

Private Property SortOrder() As String

  Get

    Dim o As Object = ViewState("SortOrder")

    If o Is Nothing Then

      Return String.Empty

    Else

      Return o.ToString

    End If

  End Get

  Set(ByVal Value As String)

    ViewState("SortOrder") = Value

  End Set

End Property

 

Page_Loadのイベントハンドラでは、Webページが初期ロードされたとき得意先IDで並べ替えさせるために、SortExpressionプロパティに「CustomerID」を設定してから、BindDataGridメソッドを実行します。

 

Private Sub Page_Load(...) Handles MyBase.Load

  If Not IsPostBack Then

    SortExpression = "CustomerID"

    BindDataGrid()

  End If

End Sub

 

BindDataGridでは、CreateDataViewメソッドを実行して得意先テーブルのDataViewを作成したら、Sortプロパティに並べ替えするフィールドと並べ替え順を設定して並べ替えします。並べ替えするフィールドは、SortExpressinプロパティから取得します。並べ替え順は、SortOrderプロパティから取得します。Webページが最初にロードされたときは、DataViewSortプロパティには「CustomerID」が設定されますので、得意先IDの昇順に並べ替えされて表示されます。

 

DataGridの列見出しの右側に昇順「▼」、降順「▲」を意味する矢印を表示するには、UpdateColumnHeaderメソッドを実行します。このメソッドの引数には、DataGridIDを指定します。

 

Sub BindDataGrid()

 ・・・

  Dim dv As DataView = CreateDataView(strSQL)

  If SortExpression.Length > 0 Then

    strSort = SortExpression

  End If

  If SortOrder.Length > 0 Then

    strSort &= " " & SortOrder

  End If

  dv.Sort = strSort

  UpdateColumnHeader(DataGrid1)

  ・・・

End Sub

 

UpdateColumnHeaderは、DataGridColumnsコレクションからDataGridColumnオブジェクトを取得して、並べ替えの対象になっている列のヘッダーにHTML<span>…</span>タグ(矢印はこのタグ内に埋め込む)を追加します。DataGridColumnが並べ替え対象の列かどうかを調べるには、DataGridColumnSortExpressionプロパティとページクラスのSortExpressionプロパティの値を比較します。値が一致しているときは、並べ替え対象になっている列です。

 

DataGridColumnHeaderTextプロパティには列見出しが格納されています。この列見出しには、前回設定した矢印「▼▲」が含まれていますので、RegExオブジェクトのReplaceメソッドを実行して除去します。HeaderTextから<span>…</span>タグを除去するには、「(<span .*>.*</span>)」のような正規表現(※)を使用します。なお、RegExオブジェクトを使用するには、名前空間「System.Text.RegularExpressions」をインポートしておく必要があります。

 

著者のWebサイトにASP.NETの正規表現をテストするWebページを用意しましたのでご利用ください。

このWebページは、RexExオブジェクトのMatchesメソッドの結果をDataGridにバインドすることにより実現しています。(http://www.friendlysw.com/webApp/regularExpression/testRegEx.aspx)



矢印は、スタイルシート(CSS)を適用させるために<span>タグで囲って表示します。CSSの「text-decoration:none」は、ハイパーリンクの下線を表示しないことを意味します。CSSの「color:red」と「font-size:xx-small」は、矢印を赤の縮小文字で表示することを意味します。

 

リスト4DataGridの列見出しに▼▲の矢印を表示する(dg2.aspx.vb)

Sub UpdateColumnHeader(ByVal dg As DataGrid)

  Const conUpDown = "<span style='text-decoration:none; color:red; font-size:xx-small'>{0}</span>"

  For Each dgc As DataGridColumn In dg.Columns

    dgc.HeaderText = Regex.Replace(dgc.HeaderText, "(<span .*>.*</span>)", String.Empty)

    If dgc.SortExpression = SortExpression Then

      If SortOrder = "DESC" Then

        dgc.HeaderText &= String.Format(conUpDown, "")

      Else

        dgc.HeaderText &= String.Format(conUpDown, "")

      End If

    End If

  Next

End Sub

 

列の並べ替え順の切り替えは、DataGridSortCommandイベントハンドラで行います。このイベントハンドラは、DataGridの列見出しをクリックしたときに発生します。DataGridから同じ列見出しを繰り返しクリックしたときは、並べ替え順を自動的に切り替えます。たとえば、得意先IDが昇順(▼)で表示されているとき、再び得意先IDのリンクをクリックすると降順(▲)に切り替えます。

 

同じ列見出しを繰り返しクリックしたかどうか調べるには、引数eSortExpressionプロパティとページクラスのSortExpressionプロパティの値を比較します。値が一致しているときは、同じ列見出しをクリックしたことになります。e.SortExpressionにはカレントの並べ替えフィールド、Me.SortExpressionには前回の並べ替えフィールドが格納されています。

 

リスト5DataGridSortCommandイベントハンドラ (dg2.aspx.vb)

Private Sub DataGrid1_SortCommand(ByVal source As Object, _

  ByVal e As System.Web.UI.WebControls.DataGridSortCommandEventArgs) _

  Handles DataGrid1.SortCommand

  If e.SortExpression = Me.SortExpression Then

    SortOrder = IIf(SortOrder = "DESC", "ASC", "DESC")

  Else

    SortOrder = "ASC"

  End If

  Me.SortExpression = e.SortExpression

  BindDataGrid()

End Sub

 

 

5DataGridから得意先IDをクリックして降順に並べ替えた(列見出しに▲が表示される)

 

 

Tip 並べ替えを高速化する ~dg2Tips.aspx

DataGridの並べ替えを高速化するには、DataViewをキャッシングします。そのためには、BindDataGridメソッドを次のように書き換えます。

 

Private Const mconCacheKey = "CustomerDataView"

Private mdvCustomers As DataView

 

Sub BindDataGrid()

 ・・・

  mdvCustomers = Cache(mconCacheKey)

  If mdvCustomers Is Nothing Then

    mdvCustomers = CreateDataView(strSQL)

    Cache(mconCacheKey) = mdvCustomers

  End If

 ・・・

  mdvCustomers.Sort = strSort

  UpdateColumnHeader(DataGrid1)

  With DataGrid1

    .DataSource = mdvCustomers

    .DataBind()

  End With

End Sub

 

キャッシュからDataViewのオブジェクトを取得したら、すでに解放されているか確認します。DataViewが解放されている(まだ作成されていない場合も含む)ときは、CreateDataViewメソッドを実行してDataViewを作成します。ここで作成したDataViewは、ポストバックされたときに再利用するためにキャッシングします。

 

 

ASP.NET 徹底活用術のホームへ戻る