DataListに並べ替え機能を付加するには

 

   DataListに並べ替え機能を付加するサンプル

 

DataListに並べ替え機能を付加するサンプル

 

このサンプルでは、DataListに並べ替え機能を追加しています。ユーザインタフェースは、DataGridと同じようにしています。DataListのヘッダに表示されているリンクをクリックすると、そのカラムを昇順で並べ替えします。再度、同じリンクをクリックすると降順で並べ替えします。DataListの上位にステータスが表示されます。昇順に並べ替えされているときは、フィールド名の後にAsc(Ascending)が表示されます。降順に並べ替えされているときは、フィールド名の後にDesc(Descending)が表示されます。DataGridの並べ替え機能は、昇順/降順どちらかに固定ですが、このサンプルでは自動的に切り替えします。

 

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

 

  DataListに並べ替え機能を付加する方法

  カラムの並べ替えを昇順/降順に自動切換えする方法

  DataViewをキャッシュする方法

  DataViewSortプロパティの使い方

 

サンプルの行74-152では、DataListを定義しています。行76-110では、HeaderTemplateDataListのヘッダを定義しています。行80-83では、ヘッダに得意先IDのリンクを表示しています。行81では、LinkButtonTextプロパティに「ID」を設定しています。この場合、IDのように得意先IDのリンクが表示されます。行82では、CommandNameプロパティに並べ替えするフィールド名(CustomerID)を設定しています。行83では、OnCommandイベントを登録しています。このイベントでは、すべてのカラムの並べ替え処理を行います。以下、同様に得意先名、担当者名、役職部署、電話番号のリンクを定義しています。

 

111-129では、ItemTemplateDataListの奇数行に表示するアイテムを定義しています。アイテムには、得意先ID、得意先名、担当者名、役職部署、電話番号のフィールドを表示します。行114では、得意先IDを表示しています。得意先テーブルのフィールドを表示するには、<%#...%>タグ内にContainer.DataItem(“CustomerID”)のように記述します。<%#...%>タグは、データをバインドすることを意味します。行130-148では、AlternatingItemTemplateDataListの偶数行に表示するアイテムを定義しています。表示するフィールドは、ItemTemplateと同じです。行149-151では、FooterTemplateDataListのフッタを定義しています。

 

74: <asp:DataList id="dlstCustomers" runat="server"
 75:   Width="100%" >
 76:   <HeaderTemplate>
 77:     <table width="100%" cellpadding="3" cellspacing="0">
 78:     <tr class="dlstHeaderStyle">
 79:       <th>
 80:         <asp:LinkButton runat="server"
 81:           Text="ID"
 82:           CommandName="CustomerID"
 83:           OnCommand="LinkButton_Command" />
 84:       </th>
           ::::

109:     </tr>
110:   </HeaderTemplate>
111:   <ItemTemplate>
112:     <tr class="dlstItemStyle">
113:       <td>
114:         <%# Container.DataItem("CustomerID") %>
115:       </td>

::::
128:     </tr>
129:   </ItemTemplate>
130:   <AlternatingItemTemplate>

::::
148:   </AlternatingItemTemplate>
149:   <FooterTemplate>
       :::

151:   </FooterTemplate>
152: </asp:DataList>

 

Sub Page_Load()イベントでは、DataListに得意先テーブルをバインドする処理とキャッシュの処理をしています。行10では、Cacheで使用するキーを生成しています。RequestPathプロパティには、.aspxファイルのパスが格納されています。変数mstrCacheKeyには、「Customers/aspado/ch2/01/DataListSorting.aspx」が格納されます。Cacheで保存されたデータは、他の.aspxファイルと共有されないようにユニークなキーを使用します。行12-14は、ページが最初にロードされたときに実行されます。行12では、CacheRemove()メソッドでキャッシュを無効にしています。行13では、DataViewを格納している変数を初期化しています。行14では、Sub BindData()を呼び出して得意先テーブルをDataListにバインドしています。引数には、並べ替えするフィールド名を指定します。このサンプルでは、並べ替え処理を高速化するために得意先テーブルのDataViewを生成してWebサーバのメモリ上にキャッシュしています。行16では、ページがポストバックされたときにWebサーバのメモリ上にキャッシュされているDataViewを変数に保存しています。ページがポストバックされたときは、得意先テーブルのレコードを抽出する代わりにメモリ上にキャッシュされているDataViewを使用しますので並べ替え処理が高速化されます。


  9: Sub Page_Load(s As Object, e As EventArgs)
 10:   mstrCacheKey = "Customers" & Request.Path
 11:   If Not IsPostBack Then
 12:     Cache.Remove(mstrCacheKey)
 13:     mdvwCustomers = Nothing
 14:     BindData("CustomerID asc")
 15:   Else
 16:     mdvwCustomers = Cache(mstrCacheKey)
 17:   End If
 18: End Sub

 

Sub BindData()では、DataViewSortプロパティを使用して引数で指定されたフィールドで並べ替えしてDataListにバインドします。行42-44If…End Ifでは、変数mdvwCustomersDataViewが格納されているか調べています。格納されていないときは、Sub LoadData()を呼び出して得意先テーブルからレコードを抽出します。行45では、LabelTextプロパティにステータス情報を設定しています。行46では、DataViewSortプロパティに並べ替えするフィールド名を設定して並べ替えしています。たとえば、得意先IDを昇順に並べ替えするには、Sortプロパティに次のような値を設定します。昇順(Asc)/降順(Desc)のオプションを省略すると昇順が採用されます。

 

DataView.Sort = “CustomerID Asc”

 

47-48では、DataListDataSourceプロパティに並べ替えしたDataViewを設定して、DataBind()メソッドでバインドしています。これでDataListには、DataViewに格納されているレコードが表示されます。

 

41: Sub BindData(strSort As String)
 42:   If mdvwCustomers Is Nothing Then
 43:     LoadData()
 44:   End If
 45:   lblStatus.Text = "Currently Sorted on " & strSort
 46:   mdvwCustomers.Sort = strSort
 47:   dlstCustomers.DataSource = mdvwCustomers
 48:   dlstCustomers.DataBind()
 49: End Sub

 

Sub LoadData()では、OleDbConnection, OleDbDataAdapterを使用して得意先テーブルからレコードを抽出してDataViewを生成しています。行52では、SQLSelectステートメントを作成しています。Top 10のオプションを指定していますので得意先テーブルから10件のレコードが抽出されます。行53-55では、OleDbConnection, OleDbDataAdapter, DataSetのインスタンスを生成しています。OleDbConnectionの引数には、Web.configに格納されているデータベース接続情報を指定しています。OleDbDataAdapterの引数には、SQLOleDbConnectionを指定しています。行57では、OleDbDataAdapterFill()メソッドで得意先テーブルからレコードを抽出するSQLを実行してDataSetに格納しています。行58では、DataSetTablesコレクションのDefaultView()メソッドで得意先テーブルのDataViewを生成しています。行59では、DataViewWebサーバのメモリ上にキャッシュしています。DataViewをキャッシュするとき、通常Cache.Item(“Key”)=”Value”のように記述しますが、Itemプロパティを省略してCache(“Key”)=”Value”のように記述することができます。ここでキャッシュしたDataViewは、Webサーバが再起動されるまで保持されます。だだし、Webサーバの資源が不足しているときは、強制的に無効にされます。キャッシュされたデータは、CacheRemove()メソッドで強制的に無効にすることができます。また、Insert()メソッドで追加するときは、各種オプションを指定してキャッシュを無効とするタイミングを設定することができます。Cacheの各種メソッドについては、後述するTipsを参照してください。

 

51: Sub LoadData()
 52:   Dim strSQL As String = "Select top 10 * From Customers"
 53:   Dim con As New OleDbConnection(ConfigurationSettings.AppSettings("conStringNw"))
 54:   Dim da As New OleDbDataAdapter(strSQL, con)
 55:   Dim ds As New DataSet()
 57:   da.Fill(ds)
 58:   mdvwCustomers = ds.Tables(0).DefaultView
 59:   Cache(mstrCacheKey) = mdvwCustomers
 60: End Sub

 

DataListのヘッダから並べ替えのリンクをクリックすると、ページがポストバックされてPage_Load()イベント、OnCommand()イベントの順に制御が渡ります。Page_Load()イベントでは、すでに解説したようにメモリ上にキャッシュされている得意先テーブルのDataViewを変数に保存します。LinkButtonOnCommand()イベントでは、どのLinkButtonがクリックされたか調べて対応する処理を行っています。行24-30Select…End Selectでは、CommandEventArgsCommandNameプロパティを参照して、どのボタンがクリックされたか調べています。CommandNameには、得意先テーブルのフィールド名が格納されています。行22Label変数には、フィールドに対応するLabelコントロールが保存されます。lblCustomerID, lblCompanyKana,…などのLabelVisibleプロパティにはFalseが設定されていますので表示されません。これらのLabelTextプロパティには、昇順(asc)/降順(desc)のいずれかが格納されます。行32では、LinkButtonCommandNameLabelTextに格納されているデータを基に並べ替えするフィールドを生成しています。たとえば、得意先IDをクリックしたときは、”CustomerID asc””CustomerID desc”が生成されます。行33-37では、昇順/降順のオプションを切り替えています。つまり昇順のときは降順、降順のときは昇順に切り替えます。行38では、Sub BindData()を呼び出してDataListDataViewをバインドします。引数には、並べ替えするフィールド名と昇順/降順のオプションをペアで指定します。Sub BindData()では、すでに解説したように引数で指定されたフィールドで並べ替えしてDataViewをバインドします。

 

21: Sub LinkButton_Command(s As Object, e As CommandEventArgs)
 22:   Dim lbl As Label
 24:   Select e.CommandName
 25:     Case "CustomerID": lbl = lblCustomerID
 26:     Case "CompanyKana": lbl = lblCompanyKana
 27:     Case "ContactName": lbl = lblContactName
 28:     Case "ContactTitle": lbl = lblContactTitle
 29:     Case "Phone": lbl = lblPhone
 30:   End Select
 32:   Dim strSort As String = e.CommandName & " " & lbl.Text
 33:   If lbl.Text = "asc" Then
 34:     lbl.Text = "desc"
 35:   Else
 36:     lbl.Text = "asc"
 37:   End If
 38:   BindData(strSort)
 39: End Sub

 

このサンプルでは、昇順/降順の切り替えをするためにLabelコントロールにカレントの状態を保存しています。ASP.NETでは、Labelを使用する代わりにViewState()を使用することができます。ViewState()を使用して昇順/降順を自動切り替えする方法については、後述するTipsを参照してください。

 

Tip

Cacheクラスでサポートしているメソッドの使い方

 

Cacheにアイテムを追加するにはすでに解説したように、以下のように記述します。

 

Cache.Item(“Key”) = “Value”

Cache(“Key”)=”Value”

 

Cacheには、DataSet, DataTable, DataView, HashTableなどを追加することができます。キャッシュを無効にするには、CacheRemove()メソッドを使用します。

 

Cache.Remove(“Key”)

 

キャッシュが無効になったときに再度キャッシュするには、次のように記述します。

 

Dim myData As Object = Cache(“Key”)

If myData Is Nothing Then

  Cache(“Key”) = myNewData

End If

 

Cacheにアイテムを追加するとき各種オプションを指定するには、Insert()メソッドを使用します。たとえば、XMLファイルが変更されたときキャッシュを無効にするには、次のように記述します。

 

Cache.Insert(“Key”, “Value”, New CacheDependency(MapPath(“Customers.xml”)))

 

CacheDependency()オプションを使用すると、データベースが変更されたときにファイルを書き換えてキャッシュを無効にすることができます。たとえば、SQL Serverの得意先テーブルが変更されたときキャッシュを無効にするには、トリガーを使用してCustomers.txtファイルを書き換えます。

 

Cache.Insert(“Customers”, dsCustomers, New CacheDependency(“C:\Customers.txt”))

 

Create Trigger UpdateCustomersCache

On Customers

For Insert, Update, Delete

As

Declare @cmd Varchar(200)

Select @cmd = ‘echo ‘ + Cast(getDATE()  As Varchar(50)) + ‘ > C:\Customers.txt’

Exec master..xp_cmdshell @cmd, no_output

 

Cacheには、日時を指定してキャッシュを無効にする機能もあります。たとえば、キャッシュを5分後に自動的に無効にするには、次のように記述します。

 

Cache.Insert(“Key”, “Value”, Nothing, DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration)

 

この他に、スライディングポリシーを適用させてキャッシュを無効にすることもできます。次の例は、キャッシュが最後に参照されてから5分後に自動的にキャッシュを無効にします。

 

Cache.Insert(“Key”, “Value”, Nothing, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5))

 

この例では、キャッシュが5分以内に参照されている間は保持されますが、5分経過しても参照されないときは無効になります。

 

 

 

 

Tip

ViewState()を使用して昇順/降順の自動切り替えを行うには

 

Labelに昇順/降順の情報を保存する代わりにViewState()に保存するには、Sub Page_Load()Sub LinkButton_Command()を以下のように書き換えます。Page_Load()の行21-25では、ViewState()を初期化しています。行27-32では、ページがポストバックされたときにViewState()からカレントの昇順/降順情報を取得します。

 

15: Sub Page_Load(s As Object, e As EventArgs)
 17:   If Not IsPostBack Then
         :::

21:     ViewState("CustomerID") = "desc"
 22:     ViewState("CompanyKana") = "asc"
 23:     ViewState("ContactName") = "asc"
 24:     ViewState("ContactTitle") = "asc"
 25:     ViewState("Phone") = "asc"
 26:   Else
 27:     mdvwCustomers = Cache(mstrCacheKey)
 28:     mstrCustomerID = ViewState("CustomerID")
 29:     mstrCompanyKana = ViewState("CompanyKana")
 30:     mstrContactName = ViewState("ContactName")
 31:     mstrContactTitle = ViewState("ContactTitle")
 32:     mstrPhone = ViewState("Phone")
 33:   End If 
 34: End Sub

 

Sub LinkButton_Command()では、並べ替えするフィールド名と昇順/降順のオプションを生成しています。行37では、CommandEventArgsCommandNameプロパティからフィールド名を取得しています。行38-54Select…End Selectでは、フィールド名に昇順/降順のオプションを追加しています。さらに、ViewState()の昇順/降順を切り替えしています。

 

36: Sub LinkButton_Command(s As Object, e As CommandEventArgs)
 37:   Dim strSort As String = e.CommandName & " "
 38:   Select e.CommandName
 39:     Case "CustomerID"
 40:       strSort &= mstrCustomerID
 41:       ViewState("CustomerID") = IIF(mstrCustomerID="asc","desc","asc")
 42:     Case "CompanyKana"
 43:       strSort &= mstrCompanyKana
 44:       ViewState("CompanyKana") = IIF(mstrCompanyKana="asc","desc","asc")
 45:     Case "ContactName"
 46:       strSort &= mstrContactName
 47:       ViewState("ContactName") = IIF(mstrContactName="asc","desc","asc")
 48:     Case "ContactTitle"
 49:       strSort &= mstrContactTitle
 50:       ViewState("ContactTitle") = IIF(mstrContactTitle="asc","desc","asc")
 51:     Case "Phone"
 52:       strSort &= mstrPhone
 53:       ViewState("Phone") = IIF(mstrPhone="asc","desc","asc")
 54:   End Select
 55:   BindData(strSort)

56: End Sub

 

 

2-1-3 DataListのカラムに複数のフィールドを表示するには

 

   DataListのカラムに複数のフィールドを表示するサンプル

 

DataListのカラムに複数のフィールドを表示するサンプル

 

このサンプルでは、DataListのカラムにレコードの複数のフィールドを表示します。DataListの得意先のカラムには、得意先名、部署役職、担当者名、電話番号が表示されます。

 

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

 

  DataListのカラムに複数のフィールドを表示する方法

 

サンプルの行30-74では、DataListを定義しています。行32-38では、HeaderTemplateでヘッダを定義しています。行39-54では、ItemTemplateで奇数行に表示するアイテムを定義しています。行42では、得意先テーブルの得意先IDを表示しています。データベースのフィールドを表示するときは、<%#...%>タグ内に記述してバインドします。行45-51<%#...%>タグには、得意先テーブルの得意先名、部署役職、担当者名、電話番号のフィールドを記述しています。StringクラスのFormat()メソッドでは、プレースホルダーを使用して各フィールドを改行させています。プレースホルダー{0},{1},{2},{3}には、得意先名、部署役職、担当者名、電話番号が挿入されます。行55-70では、AlternatingItemTemplateで偶数行に表示するアイテムを定義しています。表示するフィールドは、ItemTemplateと同じです。行71-73では、FooterTemplateでフッタ情報を定義しています。

 

30: <asp:DataList id="dlstCustomers" runat="server"
 31:   EnableViewState="False">
 32:   <HeaderTemplate>
       ::::

38:   </HeaderTemplate>
 39:   <ItemTemplate>
 40:     <tr class="dlstItemStyle">
 41:       <td>
 42:         <%# Container.DataItem("CustomerID") %>
 43:       </td>
 44:       <td>
 45:         <%#
 46:           String.Format("{0}<br>{1}<br>{2}<br>{3}", _
 47:           Container.DataItem("CompanyName"), _
 48:           Container.DataItem("ContactTitle"), _
 49:           Container.DataItem("ContactName"), _
 50:           Container.DataItem("Phone"))
 51:         %>
 52:       </td>
 53:     </tr>
 54:   </ItemTemplate>
 55:   <AlternatingItemTemplate>
 70:   </AlternatingItemTemplate>
 71:   <FooterTemplate>
       ::::

73:   </FooterTemplate>
 74: </asp:DataList>

 

 

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

 

  6: Sub Page_Load(s As Object, e As EventArgs)
  7:   If Not IsPostBack() Then
  8:     DataBind()
  9:   End If
 10: End Sub

Sub DataBind()では、OleDbConnection, OleDbDataAdapterクラスを使用してデータベースから得意先テーブルのレコードを抽出してDataSetに格納しています。さらに、DataSetDataListDataSourceプロパティに設定してDataBind()メソッドでバインドしています。これで、得意先テーブルがDataListに表示されます。


 12: Sub DataBind()
 13:   Dim strSQL As String = "Select Top 5 * From Customers"
 14:   Dim con As New OleDbConnection(ConfigurationSettings.AppSettings("conStringNw"))
 15:   Dim da As New OleDbDataAdapter(strSQL, con)
 16:   Dim ds As New DataSet()
 18:   da.Fill(ds)
 19:   dlstCustomers.DataSource = ds
 20:   dlstCustomers.DataBind()
 21: End Sub

 

ASP.NET DataListのホームへ戻る