DataGridの並べ替えをカスタマイズするには

 

  DataGridの並べ替えにオートリバース機能を付加するサンプル

DataGridの並べ替えにオートリバース機能を付加するサンプル

 

このサンプルは、DataGridを並べ替えするとき昇順/降順を自動的に切り替えます。並べ替えが適用されているカラムのヘッダには、昇順()、降順()の矢印が表示されます。DataGridのヘッダにマウスを移動すると、「Sort by: CustomerID desc」のようなツールチップが表示されます。昇順()で並べ替えられているカラムのリンクを再度クリックすると、降順()で並べ替えします。

 

このサンプルでは、以下のノウハウを習得することができます。

 

  DataGridに並べ替え機能を追加する方法

  昇順/降順の切り替えを自動的に行う方法

  DataGridのヘッダに昇順/降順の矢印を表示する方法

  DataGridのヘッダにツールチップを表示する方法

  ViewStateにデータを保存する方法

  DataViewWebサーバのメモリ上にキャッシュする方法

 

サンプルの行115-142では、DataGridを定義しています。行117では、DataGridAllowSortingプロパティにTrueを設定して並べ替え機能を使用するようにしています。行118では、OnItemCreateイベントを登録しています。このイベントは、DataGridをバインドしてアイテムが作成されたときに発生します。行119では、OnSortCommandイベントを登録しています。このイベントは、DataGridのヘッダに表示されている並べ替えのリンクをクリックしたときに発生します。行128-141<Columns>…</Columns>では、BoundColumnで得意先テーブルの得意先ID、フリガナ、得意先名、電話番号をバインドしています。得意先ID、フリガナ、電話番号のBoundColumnには、SortExpressionプロパティに得意先テーブルのフィールド名を設定しています。SortExpressionにフィールド名を設定すると、ヘッダに並べ替えのリンクが表示されます。

 

115: <asp:DataGrid id="dgrdCustomers" runat="server"
117:   AllowSorting="True"
118:   OnItemCreated="dgrdCustomers_ItemCreated"
119:   OnSortCommand="dgrdCustomers_SortCommand"
       :::: >
128:   <Columns>
129:     <asp:BoundColumn
130:       DataField="CustomerID" HeaderText="ID"
131:       SortExpression="CustomerID"
132:       ItemStyle-HorizontalAlign="Right" />
133:     <asp:BoundColumn
134:       DataField="Kana" HeaderText="
フリガナ"
135:       SortExpression="Kana" />
136:     <asp:BoundColumn
137:       DataField="CompanyName" HeaderText="
得意先名" />
138:     <asp:BoundColumn
139:       DataField="Phone" HeaderText="
電話番号"
140:       SortExpression="Phone" />
141:   </Columns>
142: </asp:DataGrid>

 

Page_Load()イベントの行12では、Cacheのキーを生成しています。ここで生成したキーを使用して、得意先テーブルのDataViewWebサーバのメモリ上にキャッシュします。変数mstrCacheKeyには、以下のようなキーが格納されます。

 

mstrCacheKey = “Customers/aspado/ch2/03/DataGridSortingAutoReverse.aspx”

 

14-17は、ページが最初にロードされたときに実行されます。行14-15では、前回キャッシュされたDataViewを強制的に無効にしています。行16では、ViewStateにカレントの並べ替えフィールドを保存しています。行17では、Sub BindData()を呼び出してDataGridに得意先のDataViewをバインドしています。BindData()の引数には、並べ替えするフィールドと昇順(ASCending)/降順(DESCending)のオプションを指定します。ページが最初にロードされたときは、引数に”CustomerID asc”を指定して得意先IDを昇順に並べ替えします。行19は、ページがポストバックされたときに実行されます。ページがポストバックされたときは、Webサーバのメモリ上にキャッシュされている得意先テーブルのDataViewを変数に保存します。ここで保存したDataViewは、Sub BindData()で並べ替えするときに使用します。

 

11: Sub Page_Load()
 12:   mstrCacheKey = "Customers" & Request.Path
 13:   If Not IsPostBack Then
 14:     Cache.Remove(mstrCacheKey)
 15:     mdvwCustomers = Nothing
 16:     ViewState("CurrentSortExpression") = "CustomerID"

17:     BindData("CustomerID asc")
 18:   Else
 19:     mdvwCustomers = Cache(mstrCacheKey)
 20:   End If
 21: End Sub

 

Sub BindData()では、DataViewを並べ替えしてDataGridにバインドします。行48-50If…End Ifでは、得意先テーブルのキャッシュが無効かチェックしています。キャッシュが無効になっているときは、Sub LoadData()を呼び出してデータベースから得意先テーブルを抽出してキャッシュします。行52では、DataViewSortプロパティに並べ替えするフィールド名を設定して並べ替えします。行53-54では、DataGridDataSourceプロパティに並べ替えしたDataViewを設定して、DataGrid()メソッドでバインドします。

 

47: Sub BindData(strSortExpression As String)
 48:   If mdvwCustomers Is Nothing Then
 49:     LoadData()
 50:   End If
 52:   mdvwCustomers.Sort = strSortExpression
 53:   dgrdCustomers.DataSource = mdvwCustomers
 54:   dgrdCustomers.DataBind()
 55: End Sub

 

Sub LoadData()の行65では、OleDbDataAdapterFill()メソッドで得意先テーブルをDataSetに格納しています。行66では、DataSetから得意先テーブルのDataViewを生成しています。行67では、DataViewをキャッシュしています。Webサーバのメモリ上にキャッシュされたDataViewは、Webサーバの資源が不足すると強制的に解放されます。キャッシュされたDataViewを使用するときは、無効になっていないかチェックする必要があります。

 

57: Sub LoadData()

::::
 65:   da.Fill(ds)
 66:   mdvwCustomers = ds.Tables(0).DefaultView
 67:   Cache(mstrCacheKey) = mdvwCustomers
 68: End Sub

 

DataGridのヘッダから並べ替えのリンクをクリックすると、OnSortCommandイベントが発生します。このイベントでは、並べ替えするフィールドを生成してSub BindData()に渡します。行25では、DataGridSortCommandEventArgsSortExpressionプロパティから値を取得して変数に保存しています。SortExpressionには、BoundColumnSortExpressionプロパティに設定している値が格納されています。行28では、ViewStateにカレントの並べ替えフィールドを保存しています。ここで保存したViewStateは、DataGridOnItemCreateイベントで参照します。行29-36Select…End Selectでは、得意先ID、フリガナ、電話番号のLabelコントロールを変数に保存しています。これらのLabelには、昇順/降順を切り替えするためにカレントの状態を保存しています。また、Visibleプロパティには、Falseが設定されていますのでブラウザには表示されません。行38では、LabelTextプロパティに格納されている昇順/降順のオプションを追加しています。行39-43If…Else…Enf Ifでは、LabelTextプロパティに格納されている昇順/降順を切り替えています。行44では、Sub BindData()を呼び出して、DataGridDataViewをバインドしています。BindData()の引数には、並べ替えするフィールドを指定します。

 

このサンプルでは、昇順/降順を自動的に切り替えるためにカレントの情報をLabelTextプロパティに格納して保存しています。ASP.NETでは、Labelに保存する代わりにViewStateに保存することができます。

 

23: Sub dgrdCustomers_SortCommand( _
 24:   s As Object, e As DataGridSortCommandEventArgs)
 25:   Dim strSortExpression As String = e.SortExpression
 26:   Dim lbl As Label
 27:
 28:   ViewState("CurrentSortExpression") = strSortExpression
 29:   Select strSortExpression
 30:     Case "CustomerID"
 31:       lbl = lblCustomerID
 32:     Case "Kana"
 33:       lbl = lblKana
 34:     Case "Phone"
 35:       lbl = lblPhone
 36:   End Select
 37:
 38:   strSortExpression &= " " & lbl.Text
 39:   If lbl.Text = "asc" Then
 40:     lbl.Text = "desc"
 41:   Else
 42:     lbl.Text = "asc"
 43:   End If
 44:   BindData(strSortExpression)
 45: End Sub

 

Sub BindData()で、DataGridDataViewをバインドすると、アイテムが作成されたときにOnItemCreatedイベントが発生します。このイベントでは、DataGridのヘッダにLabelコントロールを追加して昇順、降順の矢印を表示します。また、ヘッダのTableCell.ToolTipプロパティにツールチップを設定します。行71では、DataGridItemTypeを変数に保存しています。行75-95For…Nextは、ItemTypeHeaderのときに実行されます。行76では、DataGridItemCells()コレクションからカレントのTableCellを取得して変数に保存しています。行77では、DataGridColumns()コレクションからSortExpressionプロパティを取得して変数に保存しています。SortExpressionには、BoundColumnSortExpressionに設定した値が格納されています。行79-93は、SortExpressionに値が設定されているときに実行されます。BoundColumnの得意先名には、SortExpressionが設定されていませんので得意先ID、フリガナ、電話番号のときに実行されます。行79-85では、TableCellToolTipプロパティに「Sort by: FieldName Asc|Desc」を設定しています。フィールド名は、Columns()コレクションのSortExpressionプロパティから取得した値を使用します。昇順(Asc)、降順(Desc)のオプションは、LabelTextプロパティから取得した値を使用します。行86では、ViewStateに保存されているカレントの並べ替えフィールドを変数に退避します。行88-92は、カレントとViewStateに保存されている並べ替えフィールドが一致するきに実行されます。行88では、Labelコントロールを生成しています。行89では、LabelTextプロパティに昇順、降順の矢印を設定しています。行90では、LabelFont.SizeプロパティにXXSmallを設定して矢印が縮小文字で表示されるようにしています。行91では、LabelForeColorRedを設定して矢印を赤色で表示するようにしています。行92では、カレントのTableCellLabelを追加しています。これで、DataGridのヘッダに昇順/降順の矢印が表示されます。

 

70: Sub dgrdCustomers_ItemCreated(s As Object, e As DataGridItemEventArgs)
 71:   Dim lit As ListItemType = e.Item.ItemType
 73:   If lit = ListItemType.Header Then
 74:     Dim i As Integer
 75:     For i=0 to dgrdCustomers.Columns.Count -1
 76:       Dim cell As TableCell = e.Item.Cells(i)
 77:       Dim strSortExpression As String = dgrdCustomers.Columns(i).SortExpression
 78:       If strSortExpression <> "" Then
 79:         Dim lbl As Label
 80:         Select strSortExpression
 81:           Case "CustomerID": lbl = lblCustomerID
 82:           Case "Kana": lbl = lblKana
 83:           Case "Phone": lbl = lblPhone
 84:         End Select
 85:         cell.ToolTip = "Sort by: " & strSortExpression & " " & lbl.Text

86:         Dim strCurrentSortExpression As String = CType(ViewState("CurrentSortExpression"), String)
 87:         If strCurrentSortExpression = strSortExpression Then             
 88:           Dim lblOrder As Label = New Label()
 89:           lblOrder.Text = IIF(lbl.Text = "asc"," ▲"," ▼")
 90:           lblOrder.Font.Size = FontUnit.XXSmall
 91:           lblOrder.ForeColor = Color.Red
 92:           cell.Controls.Add(lblOrder)
 93:         End If
 94:       End If
 95:     Next
100:   End If
101: End Sub

 

DataGridの複数のカラムを並べ替えるサンプル

 

ダウンロードにDataGridの複数のカラムを並べ替えるサンプルが収録されています。

DataGridの複数のカラムを並べ替えするサンプル

 

DataGridのヘッダの見出しをクリックすると、その見出しを並べ替えします。見出しに番号①-④がついているとき、見出しをクリックすると昇順/降順を自動的に切り替えて並べ替えします。番号①-④をクリックすると並べ替えを解除します。

 

 

  DataGrid50音順に表示するサンプル

DataGrid50音順に表示するサンプル

 

このサンプルは、DataGrid上に得意先を50音順に並べ替えて表示します。たとえば、フッタに表示されている「カ」をクリックするとカ行(カキクケコガギグゲゴ)の得意先が表示されます。カ行をクリックしたときは、カキクケコの他に濁音ガギグゲゴで始まる得意先も含まれます。ハ行をクリックしたときは、濁音(バビブベボ)と半濁音(パピプペポ)も含まれます。このサンプルを応用すると、得意先を都道府県別、売上高のABC分析別に表示することができます。

 

このサンプルでは、以下のノウハウを習得することができます。

 

  DataGridのフッタにLiteralControlを追加する方法

  DataGridのフッタにLinkButtonを追加する方法

  DataGridのセルを削除する方法

  DataGridのセルを結合する方法

  得意先テーブルを50音順で絞り込む方法

  サブプロシージャの引数にデフォルト値を設定する方法

 

サンプルの行83-101では、DataGridを定義しています。行89では、DataGridOnItemCommandイベントを登録しています。このイベントは、フッタに表示されている50音のLinkButtonをクリックすると発生します。行90では、OnItemCreateイベントを登録しています。このイベントは、DataGridDataBind()メソッドを実行してアイテムが作成されたときに発生します。行95-100<Columns>…</Columns>では、BoundColumnで得意先テーブルのカナ、得意先名、担当者名、電話番号をバインドしています。

 

83: <asp:DataGrid id="dgrdCustomers" runat="server"

::::
 89:   OnItemCommand="dgrdCustomers_ItemCommand"
 90:   OnItemCreated="dgrdCustomers_ItemCreated">

::::
 95:   <Columns>
 96:     <asp:BoundColumn DataField="Kana" HeaderText="
カナ" />
 97:     <asp:BoundColumn DataField="CompanyName" HeaderText="
得意先名" />
 98:     <asp:BoundColumn DataField="ContactName" HeaderText="
担当者名" />
 99:     <asp:Boundcolumn DataField="Phone" HeaderText="
電話番号" />
100:   </Columns>
101: </asp:DataGrid>

 

Page_Load()イベントでは、ページが最初にロードされたときSub BindData()を呼び出して、DataGridに得意先テーブルをバインドしています。

 

  6: Sub Page_Load()
  7:   If Not IsPostBack Then
  8:     BindData()
  9:   End If
 10: End Sub

 

Sub BindData()の行14-22If…Else…End Ifでは、得意先テーブルからレコードを抽出するSQLを生成しています。行15-17は、引数を省略したときに実行されます。引数を省略するとア行の得意先を抽出するSelectステートメントを生成します。Where句には、CompanyKana Like '[アイウエオ]%'を指定してア行で始まる得意先を抽出します。'[アイウエオ]%'の代わりに'[-]%'のように記述することもできます。Order By句には、CompanyKanaを指定して得意先の読みの順に並べ替えます。

 

19-21は、引数を指定したときに実行されます。SelectステートメントのWhere句には、引数に指定したフィルタ条件を設定します。Order By句には、CompanyKanaを指定して得意先の読みの順に並べ替えます。

 

28では、OleDbDataAdapterFill()メソッドでSelectステートメントを実行して、DataSetに得意先テーブルを格納します。行29-30では、DataGridDataSourceプロパティにDataSetを設定して、DataBind()メソッドでバインドしています。

 

12: Sub BindData(Optional strKana As String = "")
 13:   Dim strSQL As String
 14:   If strKana = String.Empty Then
 15:     strSQL = "Select Left(CompanyKana,3) As Kana, CompanyName, ContactName, Phone

From Customers" _
 16:       & " Where CompanyKana Like '[
アイウエオ]%'" _
 17:       & " Order By CompanyKana"
 18:   Else
 19:     strSQL = "Select Left(CompanyKana,3) As Kana, CompanyName, ContactName, Phone

From Customers" _
 20:       & " Where CompanyKana Like '[" & strKana & "]%'" _
 21:       & " Order By CompanyKana"
 22:   End If

::::
 28:   da.Fill(ds, "Customers")
 29:   dgrdCustomers.DataSource = ds
 30:   dgrdCustomers.DataBind()
 31: End Sub

 

DataGridDataBind()メソッドが実行されると、アイテムが作成されたときにOnItemCreatedイベントが発生します。このイベントでは、DataGridのフッタに50音のLinkButtonを表示します。行34-37では、ア行、カ行、・・・の文字列を定義しています。ここで定義した文字列は、LinkButtonCommandArgumentプロパティに設定します。行41-60は、ItemTypeFooterのときに実行されます。行41では、TableCellCollectionClear()メソッドでフッタのセルを削除しています。行42-43では、TableCellを生成してフッタに追加しています。ここで追加したTableCellColumnSpanプロパティには4を設定して結合しています。

 

45-47では、LiteralControlを生成してTableCellに追加しています。LiteralControlTextプロパティには「ページング:」が設定されていますので、フッタに表示されます。このようにTableCellにテキスト文字を追加するときは、LiteralControlを使用します。行48-60For…Nextでは、ア行、カ行、・・・のLinkButtonを生成してTableCellに追加しています。LinkButtonCommandNameプロパティには、kanaを設定しています。CommandArgumentプロパティには、SelectステートメントのWhere句で使用するフィルタ条件を設定します。たとえば、ア行のLinkButtonのときは「アイウエオ」が設定されます。LinkButtonの前後には、LiteralControlで生成した[]が表示されます。

 

33: Sub dgrdCustomers_ItemCreated(s As Object, e As DataGridItemEventArgs)
 34:   Dim astrKana As String() =  {"
アイウエオ","カキクケコガギグゲゴ", _
 35:     "
サシスセソザジズゼゾ","タチツテトダヂズデド","ナニヌネノ", _
 36:     "
ハヒフヘホバビブベボパピプペポ","マミムメモ","ヤユヨ", _
 37:     "
ラリルレロ","ワヲン"}
 40:   If e.Item.ItemType = ListItemType.Footer Then
 41:     e.Item.Cells.Clear()
 42:     Dim tc As New TableCell()
 43:     tc.ColumnSpan = 4
 44:     e.Item.Cells.Add(tc)
 45:     Dim lcKana As New LiteralControl()
 46:     lcKana.Text = "
ページング: "
 47:     tc.Controls.Add(lcKana)
 48:     For i=0 To astrKana.Length-1
 49:       Dim lb As New LinkButton()
 50:       Dim lcLeft As New LiteralControl()
 51:       Dim lcRight As New LiteralControl()
 52:       lcLeft.Text = "["
 53:       lcRight.Text = "]
 "
 54:       lb.Text = left(astrKana(i),1)
 55:       lb.CommandName = "kana"
 56:       lb.CommandArgument = astrKana(i)
 57:       tc.Controls.Add(lcLeft)
 58:       tc.Controls.Add(lb)
 59:       tc.Controls.Add(lcRight)
 60:     Next
 61:   End If
 62: End Sub

 

DataGridのフッタから50音のLinkButtonをクリックすると、OnItemCommandイベントが発生します。このイベントでは、CommandNameプロパティを参照してどのLinkButtonがクリックされたか調べます。CommandName”kana”が格納されているときは、Sub BindData()を呼び出してDataGridに得意先テーブルをバインドします。Sub BindData()の引数には、CommandArgumentプロパティの値を指定します。CommnadArgumentには、SelectステートメントのWhere句に指定するフィルタ条件が格納されています。

 

64: Sub dgrdCustomers_ItemCommand(s As Object, e As DataGridCommandEventArgs)
 65:   If e.CommandName = "kana" Then
 66:     BindData(e.CommandArgument)
 67:   End If
 68: End Sub

ASP.NET DataGridのホームへ戻る