DataGridに並べ替え機能を追加したサンプル

 

 

DataGridに並べ替え機能を追加したサンプル

 

このサンプルは、親ウィンドウのDataGridに表示されているレコードを並べ替えることができます。DataGridのレコードを並べ替えるには、親ウィンドウから並べ替えボタンをクリックします。並べ替えボタンをクリックすると、子ウィンドウが表示されます。

 

並べ替えするカラムを選択するには、子ウィンドウのListBoxから得意先テーブルのカラム(フィールド)を選択して、[追加]ボタンをクリックします。並べ替え順のボックスに、項番、カラム名、ドロップダウンリスト、削除ボタンが表示されます。ドロップダウンリストには、昇順がデフォルトで表示されます。降順に並べ替えするときは、切り替えます。[削除]ボタンをクリックすると、選択したカラムがListBoxに戻ります。複数のカラムを並べ替えるときは、同様の手順でListBoxからカラムを選択します。

 

カラムの選択が完了したら、[適用]ボタンをクリックします。適用ボタンをクリックすると、親ウィンドウのDataGridが並べ替えられます。適用ボタンをクリックしても、子ウィンドウは開いた状態になっていますので、並べ替え条件を変えて繰り返すことができます。

 

親ウィンドウのDataGridには、得意先テーブルのすべてのレコードが表示されます。デフォルトでは、得意先IDの昇順に表示されます。通常、Webページがポストバックされると位置情報が失われてDataGridの先頭から表示されます。このサンプルでは、DataGridの位置情報を保持していますのでWebページがポストバックされても選択したアイテムが画面に表示されます。

 

 

◆プログラムDataGridSorting.aspx/PopupSort.aspxのポイント

 

¶ポイント1 子ウィンドウから選択したカラムを親ウィンドウに渡すには

 

このサンプルでは、子ウィンドウから選択したカラムを親ウィンドウに渡すのに、TextBoxを経由しています。子ウィンドウから選択したカラムを親ウィンドウのTextBoxに渡すには、JavaScriptで記述したコードをブラウザから実行させます。親ウィンドウのTextBoxが書き換えられると、WebページがポストバックされてDataGridが並べ替えられます。

 

TextBoxが書き換えられたときにWebページをポストバックさせるには、TextBoxにクライアント側で動作するonPropertyChangeイベントを登録します。このイベントでは、Page.GetPostBackEventReference()メソッドが生成したJavaScriptを実行させてWebページをポストバックします。

 

このように、GetPostBackEventReference()メソッドを使用すると、本来ポストバックしないWebコントロールにポストバックする機能を追加することができます。

 

¶ポイント2 ポストバックしたときにDataGridの位置情報を保持するには

 

ポストバックしたときにDataGridの位置情報を保持するには、@ PageディレクティブにSmartNavigation="false"を追加します。ところが、このサンプルのようにRegisterClientScriptBlock()メソッドでJavaScriptを登録して実行させるとき、正常に動作しません。このサンプルでは、SmartNavigation機能を使用する代わりにブックマーク機能を応用してDataGridの位置情報を保持しています。

 

¶ポイント3 DataGridに定義されているDropDownListのデフォルト値を選択するには

 

DataGridTemplateColumnに定義されているDropDownListのデフォルト値を選択するには、OnItemDataBoundイベントを利用します。DropDownListItemsコレクションからデフォルトのアイテムを検索するには、ItemsコレクションのFindByValue()/FindByText()メソッドを使用します。

 

dropSortOrder.Items.FindByValue("asc").Selected = True

 

 

¶ポイント4 イベントが発生したコントロールの親のコントロールを取得するには

 

このサンプルでは、DataGridに定義されているDropDownListOnSelectedIndexChangedイベントからDataGridDataGridItemのコントロールを取得するのに、NamingContainerを使用しています。

 

Dim dgi As DataGridItem = CType(CType(source, Control).NameingContainer, DataGridItem)

Or

Dim dgi As DataGridItem = CType(CType(source, Control).Parent.Parent, DataGridItem)

 

 

¶ポイント5 DataGridにシーケンス番号を表示するには

 

DataGridにシーケンス番号を表示するには、TemplateColumnItemTemplateGetSequence()関数をバインドします。この関数では、0から始まるシーケンス番号を生成して返します。

 

Private mintSequence As Integer = 0

Function GetSequence() As Integer

  mintSequence += 1

  Return mintSequence

End Function

 

<asp:TemplateColumn>

  <ItemTemplate>

    <%# GetSequence() %>

  </ItemTemplate>

</asp:TemplateColumn>

 

 

◆メインプログラムDataGridSorting.aspxの解説(HTML)

 

DataGridSorting.aspxのプレゼンテーションコンテンツの部分について解説します。行161-167ImageButtonでは、並べ替えのボタンを定義しています。行168-174LabelTextBoxでは、件数を表示しています。

 

並べ替えのボタンと件数を表示

 

187-240では、DataGridを定義しています。このDataGridには、AutoGenerateColumnsプロパティにFalseを設定してカラムの自動生成機能を抑止しています。行201-239<Columns>…</Columns>では、TemplateColumnBoundColumnを定義しています。行202-213TemplateColumnでは、ItemTemplate<a>タグとLinkButtonを定義しています。<a>は、ブックマークとして使用します。ここで定義したブックマークは、DataGridの位置情報を保持するのに使用します。LinkButtonは、レコードセレクターとして使用します。

 

214-218BoundColumnでは、得意先テーブルの得意先IDをバインドしています。後続する、BoundColumnでは、得意先テーブルの得意先名、担当者名、役職、電話番号、都道府県をバインドしています。

 

DataGridに得意先テーブルを表示した例

 

249-254では、メッセージを表示するTextBoxを定義しています。このTextBoxReadOnlyプロパティには、Trueを設定して読み込み専用にしています。

 

259-262では、Buttonを定義しています。このButtonVisibleプロパティには、Falseを設定して非可視状態にしています。このButtonにはOnClickイベントが登録されています。OnClickイベントは、子ウィンドウから親ウィンドウをポストバックさせたときに実行されます。

 

リスト DataGridSorting.aspxのソースコード(HTML)

141: <html>
147: <body>
156: <form id="frmMain" runat="server">
161: <asp:ImageButton id="ibtnSort" runat="server"
162:   CommandName="sort"
163:   OnCommand="ibtnSort_Command"
164:   ImageUrl="../img/sort.gif"
167:   ImageAlign="Middle"         />
168: <asp:Label id="lblRows" runat="server"
169:   Text="
件数"
170:   CssClass="rowNumber" />
171: <asp:TextBox id="txtRows" runat="server"
172:   CssClass="rowNumber"
173:   Columns="3"
174:   ReadOnly="True" />
187: <asp:DataGrid id="dgrdCustomers" runat="server"
188:   AutoGenerateColumns="False"
189:   OnItemCommand="dgrdCustomers_ItemCommand"
190:   OnItemDataBound="dgrdCustomers_ItemDataBound" :::
196:   EnableViewState="True">
         
・・・

201:   <Columns>
202:     <asp:TemplateColumn
203:        HeaderText="<div class='dgrdHeaderBox'>1</div>">
204:        <ItemTemplate>
205:          <a name='#<%# GetBookMarkID() %>'></a>
206:          <asp:LinkButton id="lbtnSelect" runat="server"
207:            CommandName="Select"
208:            Text="<div class='dgrdItemArrow'>4</div>"
209:            Visible="True" />
210:        </ItemTemplate>
213:     </asp:TemplateColumn>
214:     <asp:BoundColumn
215:        DataField="CustomerID"
216:        HeaderText="<div class='dgrdHeader'>ID</div>">
218:     </asp:BoundColumn>
          
・・・

239:   </Columns>
240: </asp:DataGrid>
249: <asp:TextBox id="txtMessage" runat="server"
252:   Columns="107"
253:   Visible="True"
254:   ReadOnly="True" />
259: <asp:Button id="btnRefresh" runat="server"
260:   Text="Hidden"
261:   Visible="False"
262:   OnClick="btnRefresh_Click" />
263: </form>
264: </body>
264: </html>

 

 

◆メインプログラムDataGridSorting.aspxの解説(コード編)

 

DataGridSorting.aspxは、子ウィンドウから並べ替えるカラムを取得してDataGridを並べ替えします。子ウィンドウから選択したカラムは、TextBoxを経由して親ウィンドウに渡します。

 

Sub Page_Load()イベントの処理

 

このイベントは、DataGridSorting.aspxがロードされたときに実行されます。このイベントでは、クライアント側で動作するイベントの登録と、DataGridに得意先テーブルをバインドします。

 

9では、メッセージを表示するTextBoxにクライアント側で動作する、onPropertyChangeイベントを登録しています。onPropertyChangeイベントでは、Webページをポストバックします。GetPostBackEventReference()メソッドは、WebページをポストバックするJavaScriptを生成します。Webページがポストバックされると、btnRefreshイベントが実行されます。

 

10-12If…End Ifでは、ページが最初にロードされたか調べています。ページが最初にロードされたときは、BindDataGrid()を呼び出してDataGridに得意先テーブルをバインドします。

 

 

  8: Sub Page_Load()
  9:   txtMessage.Attributes.Add("OnPropertyChange", GetPostBackEventReference(btnRefresh))
 10:   If Not IsPostBack Then
 11:     BindDataGrid()
 12:   End If
 13: End Sub

 

 

Sub dgrdCustomers_ItemDataBound()イベントの処理

 

このイベントは、DataGridDataBind()メソッドが実行されたときに発生します。このイベントでは、DataGridのアイテム(DataGridItem)にクライアント側で動作するonClickイベントを登録します。これにより、DataGridの任意のセルをクリックして行を選択できるようになります。

 

45: Sub dgrdCustomers_ItemDataBound(s As Object, e As DataGridItemEventArgs)
 46:   Dim lit As ListItemType = e.Item.ItemType
 47:
 48:   If lit = ListItemType.Item OrElse _
 49:     lit = ListItemType.AlternatingItem OrElse _
 50:     lit = ListItemType.SelectedItem Then
 51:     Dim lbtn As LinkButton = CType(e.Item.FindControl("lbtnSelect"), LinkButton)
 52:     e.Item.Attributes("onClick") = GetPostBackClientHyperlink(lbtn, "")
 53:     e.Item.Style("cursor") = "hand"
 54:   End If
 55: End Sub

 

 

Sub dgrdCustomers_ItemCommand()イベントの処理

 

このイベントは、DataGridから行を選択したときに発生します。このイベントでは、InsertBookmarkScript()を呼び出してクライアント側で動作するJavaScriptを登録します。InsertBookmarkScriptの引数には、DataGridから選択したアイテムのインデックス番号を指定します。

 

57: Sub dgrdCustomers_ItemCommand(s As Object, e As DataGridCommandEventArgs)
 58:   If e.CommandName = "Select" Then
 60:     InsertBookmarkScript(e.Item.ItemIndex)
 61:   End If
 62: End Sub

 

 

Sub ibtnSort_Command()イベントの処理

 

このイベントは、Webページから並べ替えのボタンをクリックしたときに発生します。このイベントでは、InsertScriptBlock()を呼び出して、子ウィンドウを開きます。

 

64: Sub ibtnSort_Command(s As Object, e As CommandEventArgs)
 65:   InsertScriptBlock()
 66: End Sub

 

 

Sub btnRefresh_Click()イベントの処理

 

このイベントは、クライアント側からメッセージを表示するTextBoxを書き換えたときに発生します。このサンプルでは、子ウィンドウから親ウィンドウのTextBoxにメッセージを設定して書き換えます。つまり、子ウィンドウから親ウィンドウをポストバックさせています。btnRefresh_Clickイベントでは、DataGridを並べ替えて再表示します。

 

17では、TextBoxに格納されているカラムの並べ替え情報を取得しています。行19-24では、カラムの並べ替え情報の有無を調べています。並べ替え情報がないときは、SELECTステートメントにORDER BY句を追加しません。並べ替え情報があるときは、SELECTステートメントのORDER BY句にカラムの並べ替え情報を指定します。

 

27では、CreateDataSet()関数を呼び出して得意先テーブルのDataSetを作成します。CreateDataSetの引数には、SQLSELECTステートメントを指定します。

 

32-37With…End Withでは、DataGridに得意先テーブルのDataViewをバインドしています。

 

38では、TextBoxに得意先テーブルのレコード件数を設定しています。レコード件数は、DataTableRowsコレクションのCountプロパティから取得します。

 

15: Sub btnRefresh_Click(s As Object, e As EventArgs)
 16:   Dim strSQL As String
 17:   Dim strSortExpression As String = txtMessage.Text.Trim()
 18:
 19:   If strSortExpression = String.Empty Then
 20:     strSQL = "Select * From Customers"
 21:   Else
 22:     strSQL = "Select * From Customers" & _
 23:       " Order By " & strSortExpression
 24:   End If
 25:   txtMessage.Text = strSortExpression
 26:
 27:   Dim ds AS DataSet = CreateDataSet(strSQL)
 28:   If ds Is Nothing Then
 29:     txtRows.Text = String.Empty
 30:     Exit Sub
 31:   End If
 32:   With dgrdCustomers
 33:     .DataSource = ds.Tables(0).DefaultView()
 34:     .DataKeyField = "CustomerID"
 35:     .DataBind()
 36:     .SelectedIndex = -1
 37:   End With
 38:   txtRows.Text = ds.Tables(0).Rows.Count.ToString()
 39: End Sub

 

 

Sub BindDataGrid()の処理

 

このサブプロシージャでは、DataGridに得意先テーブルをバインドして表示します。BindDataGridは、Page_Loadイベントから呼ばれます。

 

 

68: Sub BindDataGrid()
 69:   Dim strSQL As String = "Select * From Customers"
 70:   Dim ds AS DataSet = CreateDataSet(strSQL)
 71:   With dgrdCustomers
 72:     .DataSource = ds.Tables(0).DefaultView()
 73:     .DataKeyField = "CustomerID"
 74:     .DataBind()
 75:     .SelectedIndex = -1
 76:   End With
 77:   txtRows.Text = ds.Tables(0).Rows.Count.ToString()
 78: End Sub

 

 

Sub InsertScriptBlock()の処理

 

このサブプロシージャでは、子ウィンドウを開くJavaScriptを生成して登録します。InsertScriptBlockは、カラムの並べ替えボタンをクリックしたときに、ボタンのOnCommandイベントから呼ばれます。

 

81-83では、JavaScriptwindow.open()メソッドの引数に指定するオプションを生成しています。行85-89With…End Withでは、StringBuilderAppend()メソッドで以下のJavaScriptを生成しています。

 

<script language='javascript'>
window.open('PopupSort.aspx','_blank','features');

</script>

 

JavaScriptwindow.open()メソッドは、新規ウィンドウを開きます。Open()メソッドの引数には、urltargetfeaturesを指定します。urlには、新規ウィンドウに表示するファイルPopupSort.aspxを指定します。

 

90では、Page.RegisterClientScriptBlock()メソッドでJavaScriptを登録します。ここで登録したJavaScriptは、Webページがロードされたときにクライアント側のブラウザから実行されます。

 

 

80: Sub InsertScriptBlock()
 81:   Dim strFeatures As String = "height=200,width=450,left=10,top=10," & _
 82:     "location=no,menubar=no,resizable=yes,scrollbars=yes," & _
 83:     "status=no,titlebar=yes,toolbar=no"
 84:   Dim sbScript As New StringBuilder()
 85:   With sbScript
 86:     .Append("<script language='javascript'>" & vbCrLf)
 87:     .Append(vbTab & "window.open('PopupSort.aspx','_blank','" & strFeatures & "');" & vbCrLf)
 88:     .Append("</" & "script>")
 89:   End With
 90:   RegisterClientScriptBlock("openWindow", sbScript.ToString)
 91: End Sub

 

 

Sub InsertBookmarkScript()の処理

 

このサブプロシージャでは、DataGridから選択した行が自動的に画面に表示されるように位置情報を保持します。DataGridがページ内に収まらないときは、ウィンドウに垂直型のスクロールバーが表示されてスクロールできるようになっています。DataGridをスクロールした状態で、Webページがポストバックされるとカレントの位置情報が失われて常に先頭行から表示されます。このサブプロシージャでは、ブックマーク機能を応用してWebページがポストバックされたときの位置を自動的に保持します。

 

InsertBookmarkScriptは、DataGridOnItemCommandイベントから呼ばれます。OnItemCommandイベントは、DataGridから行を選択したときに発生します。

 

95-99With…End Withでは、StringBuilderAppend()メソッドで以下のようなJavaScriptを生成しています。

 

<script language='javascript'>

location.href='#999';

</script>

 

JavaScriptlocation.href=では、hrefにブックマークID(#999)を設定してその位置に移動させます。このサンプルでは、DataGridの選択行のブックマークIDを設定して、その行に移動しています。つまり、選択した行が画面に表示されるようにしています。

 

100では、Page.RegisterStartupScript()メソッドでJavaScriptを登録しています。RegisterStartupScriptで登録されたJavaScriptは、Webページの最後に挿入されます。ここで登録したJavaScriptは、Webページがロードされたときにクライアント側のブラウザから実行されます。

 

93: Sub InsertBookmarkScript(intBookMarkID As Integer)
 94:   Dim sbScript As New StringBuilder()
 95:   With sbScript
 96:     .Append("<script language='javascript'>" & vbCrLf)
 97:     .Append(vbTab & "location.href='#" & intBookMarkID.ToString() & "';" & vbCrLf)
 98:     .Append("</" & "script>")
 99:   End With
100:   RegisterStartupScript("bookMark", sbScript.ToString)
101: End Sub

 

 

Function GetBookMarkID()関数の処理

 

この関数は、ブックマークのIDを生成して返します。GetBookMarkIDは、DataGridTemplateColumnがバインドされるときに呼ばれます。

 

202:       <asp:TemplateColumn >
204:         <ItemTemplate>
205:           <a name='#<%#
GetBookMarkID() %>'></a>
210:         </ItemTemplate>
213:       </asp:TemplateColumn>

 

GetBookMarkIDは、0から始まるブックマークIDを生成して返します。DataGridがバインドされると以下のような<a>タグが生成されます。

 

<a name='#0'></a>

<a name='#1'></a>

<a name='#2'></a>

:::

<a name='#49'></a>

 

114: Function GetBookMarkID() As String
115:   Dim strBookMarkID As String = mintBookMarkID.ToString()
116:   mintBookMarkID += 1
117:   Return strBookMarkID
118: End Function

 

 

Function CreateDataSet()関数の処理

 

この関数は、データベースからレコードを抽出してDataSetを作成して返します。CreateDataSetは、BindDataGrid()btnRefresh_Click()から呼ばれます。CreateDataSetのの引数には、strSQLstrConnectionStringを指定します。strSQLには、データベースからレコードを抽出するSELECTステートメントを指定します。strConnectionStringには、Web.Configに登録されている<add>タグのkeyを指定します。strConnectionStringを省略したときは、デフォルトとしてconStringAccNwを使用します。

 

<add key="conStringAccNw"

  value="PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA Source=C:\WebMatrix\webdb\Nwind.mdb" />

 

 

129: Function CreateDataSet(strSQL As String, _
130:   Optional strConnectionString As String = "conStringAccNw") As DataSet
131:   Dim con As New OleDbConnection( _
132:     ConfigurationSettings.AppSettings(strConnectionString))
133:   Dim da As New OleDbDataAdapter(strSQL, con)
134:   Dim ds As New DataSet()
135:   da.Fill(ds)
136:   Return ds
137: End Function

 

 

リスト DataGridSorting.aspxのソースコード(コード編)

  1: <%@ Page language="vb" SmartNavigation="false" %>
  2: <%@ Import Namespace="System.Data" %>
  3: <%@ Import Namespace="System.Data.OleDb" %>
  4:
  5: <script language="vb" runat="server">
  6: Private mintBookMarkID As Integer = 0
  7:
  8: Sub Page_Load()
 13: End Sub
 14:
 15: Sub btnRefresh_Click(s As Object, e As EventArgs)
 39: End Sub
 40:
 41: Sub dgrdCustomers_ItemCreated(s As Object, e As DataGridItemEventArgs)
 43: End Sub
 44:
 45: Sub dgrdCustomers_ItemDataBound(s As Object, e As DataGridItemEventArgs)
 55: End Sub
 56:
 57: Sub dgrdCustomers_ItemCommand(s As Object, e As DataGridCommandEventArgs)
 62: End Sub
 63:
 64: Sub ibtnSort_Command(s As Object, e As CommandEventArgs)
 66: End Sub
 67:
 68: Sub BindDataGrid()
 78: End Sub
 79:

 80: Sub InsertScriptBlock()

 91: End Sub

 92:

 93: Sub InsertBookmarkScript(intBookMarkID As Integer)

101: End Sub
102:
103: Sub InsertAlertScript()
112: End Sub
113:
114: Function GetBookMarkID() As String
118: End Function
119:
129: Function CreateDataSet(strSQL As String, _
130:   Optional strConnectionString As String = "conStringAccNw") As DataSet
137: End Function
139: </script>

 

 

◆サブプログラムPopupSort.aspxの解説(HTML)

 

子ウィンドウのWebフォームには、ListBoxButtonDataGridを作成しています。ListBoxには、得意先テーブルのカラム(フィールド)を表示します。DataGridには、ListBoxから選択したカラムを表示します。

 

194-199ListBoxには、得意先テーブルのカラムを表示します。ListBoxSelectionModeプロパティには、Singleを設定して1アイテムのみ選択可能にしています。また、Rowsプロパティには、6行表示するように設定しています。

 

203-205では、追加のボタンを表示します。

 

209-268では、PanelDataGirdを定義しています。このDataGridShowHeaderShowFooterプロパティにはFalseを設定して、ヘッダとフッタを非表示にしています。PanelVisibleプロパティには、Falseを設定してDataGridを非可視状態にしています。DataGridAutoGenerateColumnsプロパティには、Falseを設定してカラムの自動生成機能を抑止しています。行232-262<Columns>…</Columns>では、BoundColumnTemplateColumnButtonColumnを定義しています。

 

233-234BoundColumnには、SortOrderテーブルのIDをバインドしています。このBoundColumnVisibleプロパティには、Falseを設定して非可視状態にしています。また、ReadOnlyプロパティにTrueを設定して読み込み専用にしています。

 

235-240TemplateColumnでは、ItemTemplateGetSequence()関数をバインドしています。行241-246では、TemplateColumnItemTemplateSortOrderテーブルのSortColumnをバインドしています。行247-256TemplateColumnでは、ItemTemplateDropDownListを定義しています。このDropDownListには、昇順/降順のアイテムを表示します。

 

257-261ButtonColumnでは、削除ボタンを定義しています。

 

ListBoxButtonDataGridを表示した例

 

278-282では、「適用」と「閉じる」のボタンを定義しています。

 

「適用」、「閉じる」のボタンを表示した例

 

 

リスト PopupSort.aspxのソースコード(HTML)

172: <html>
178: <body>
180: <form runat="server">
194: <asp:ListBox id="lstSortColumns" runat="server"
195:   DataTextField="Container.DataItem.Text"
196:   DataValueField="Container.DataItem.Value"
197:   Rows="6"
198:   SelectionMode="Single">
199: </asp:ListBox>
203: <asp:Button id="btnAdd" runat="server"
204:   Text="
追加"
205:   OnClick="btnAdd_Click" />
209: <asp:Panel id="pnlSequence" runat="server"
211:   Visible="False">
221:   <asp:DataGrid id="dgrdSortOrders" runat="server"
222:      AutoGenerateColumns="False"
226:      ShowHeader="False"
227:      ShowFooter="False"
231:      EnableViewState="True">
232:      <Columns>
233:         <asp:BoundColumn DataField="ID"
234:            Visible="False" ReadOnly="True" />
235:         <asp:TemplateColumn>
236:            <ItemTemplate>
237:              <%# GetSequence() %>
238:            </ItemTemplate>
240:         </asp:TemplateColumn>
241:         <asp:TemplateColumn>
242:            <ItemTemplate>
243:              <%# Container.DataItem("SortColumn") %>
244:            </ItemTemplate>
246:         </asp:TemplateColumn>
247:         <asp:TemplateColumn>
248:            <ItemTemplate>
249:              <asp:DropDownList id="dropSortOrder" runat="server"
250:                 AutoPostBack="True"
251:                 OnSelectedIndexChanged="dropSortOrder_SelectedIndexChanged">
252:                 <asp:ListItem Text="
昇順 (Asc)" Value="Asc" />
253:                 <asp:ListItem Text="
降順 (Desc)" Value="Desc" />
254:              </asp:DropDownList>
255:            </ItemTemplate>
256:         </asp:TemplateColumn>
257:         <asp:ButtonColumn
258:            ButtonType="PushButton"
259:            CommandName="delete"
260:            Text="
削除">
261:         </asp:ButtonColumn>
262:      </Columns>
263:   </asp:DataGrid>
268: </asp:Panel>
278: <asp:Button id="btnApply" runat="server"
279:   Text="
適用"
280:   OnClick="btnApply_Click" />
281: <asp:Button id="btnClose" runat="server"
282:   Text="
閉じる" />
288: </form>
289: </body>
289: </html>

 

 

◆サブプログラムPopupSort.aspxの解説(コード編)

 

PopupSort.aspxは、Webフォームから選択したカラム情報を親ウィンドウに渡します。得意先テーブルのカラムは、ListBoxに表示して選択させます。ListBoxから選択したカラムは、DataGridに表示します。選択したカラムをListBoxに戻すには、削除ボタンをクリックします。

 

Sub Page_Load()イベントの処理

 

このイベントは、ページがロードされたときに発生します。このイベントでは、ページの初期化を行います。

 

9-18If…Else…End Ifでは、ページが最初にロードされたか調べています。最初にロードされたときは、「閉じる」ボタンにクライアント側で動作するonClickイベントを登録します。onClickイベントでは、JavaScriptwindow.close()メソッドを実行して子ウィンドウを閉じます。行11では、BindListBox()を呼び出してListBoxに得意先テーブルのカラムをバインドします。行12では、CreateDataTable()関数を呼び出してSortOrderDataTableを作成します。

 

ページがポストバックされたときは、Session変数に保存されているDataTableを取得します。Session変数にDataTableが保存されていないときは、CreateDataTable()関数を呼び出して作成します。

 

 

  8: Sub Page_Load()
  9:   If Not IsPostBack Then
 10:     btnClose.Attributes.Add("onclick", "window.close();")
 11:     BindListBox()
 12:     mdt = CreateDataTable()
 13:   Else
 14:     mdt = CType(Session("SortOrder"), DataTable)
 15:     If mdt Is Nothing Then
 16:       mdt = CreateDataTable()
 17:     End If
 18:   End If
 19: End Sub

 

 

Sub btnAdd_Click()イベントの処理

 

このイベントは、追加ボタンをクリックしたときに発生します。このイベントでは、ListBoxから選択したカラムをDataGridに表示します。

 

22-32If…End Ifでは、ListBoxからカラムを選択したか調べています。行23-27では、ListBoxから選択したカラムをDataTableに追加しています。行23では、DataTableNewRow()メソッドでDataRowを作成しています。行24-25では、ListBoxからカラムヘッダとカラム名を取得してDataRowを更新しています。行26では、並べ替え順を更新しています。行27では、DataTableRowsコレクションのAdd()メソッドでDataRowを追加しています。これで、DataTableに新規レコードが追加されます。

 

28では、ListBoxから選択したカラムを削除しています。行29では、Session変数に最新のDataTableを保存しています。行30では、BindDataGrid()を呼び出してDataGridDataTableをバインドします。行31では、PanelVisibleプロパティにTrueを設定してDataGridを可視状態にします。これで、DataGridにはListBoxから選択したカラムが表示されます。

 

21: Sub btnAdd_Click(s As Object, e As EventArgs)
 22:   If lstSortColumns.SelectedIndex <> -1 Then             
 23:     Dim dr As DataRow = mdt.NewRow
 24:       dr("SortColumn") = lstSortColumns.SelectedItem.Text
 25:       dr("SortFieldName") = lstSortColumns.SelectedItem.Value
 26:       dr("SortOrder") = "Asc"
 27:     mdt.Rows.Add(dr)
 28:     lstSortColumns.Items.RemoveAt(lstSortColumns.SelectedIndex)
 29:     Session("SortOrder") = mdt
 30:     BindDataGrid()
 31:     pnlSequence.Visible = True

32:   End If
 33: End Sub

 

 

Sub dgrdSortOrders_ItemDataBound()イベントの処理

 

このイベントは、DataGridDataBind()メソッドが実行されたときに発生します。このイベントでは、DropDownListに表示するデフォルト(昇順/降順)のアイテムを選択します。

 

37-44If…End Ifでは、ItemTypeItem、またはAlternatingItemか調べています。行39では、ItemFindControl()メソッドでDropDownListを見つけています。行40-41では、DataItem(DataRowView)からSortOrderのカラム値を取得しています。SortOrderには、Asc/Descが格納されています。行42では、DropDownListItemsコレクションのFindByValue()メソッドでItemValue値を検索しています。FindByValue()からは、Itemが返されます。ItemsコレクションのIndexOf()では、Itemのインデックス番号を返します。DropDownListSelectedIndexプロパティに、Itemのインデックス番号を設定すると、このアイテムがデフォルトになります。行42は、以下のように記述することもできます。

 

dropSortOrder.Items.FindByValue(strSortOrder).Selected = True

35: Sub dgrdSortOrders_ItemDataBound(s As Object, e As DataGridItemEventArgs)
 36:   Dim lit As ListItemType = e.Item.ItemType
 37:   If lit = ListItemType.Item OrElse _
 38:     lit = ListItemType.AlternatingItem Then
 39:     Dim dropSortOrder As DropDownList = CType(e.Item.FindControl("dropSortOrder"), DropDownList)
 40:     Dim drv As DataRowView = CType(e.Item.DataItem, DataRowView)
 41:     Dim strSortOrder As String = drv("SortOrder") ' Asc|Desc
 42:     dropSortOrder.SelectedIndex =

dropSortOrder.Items.IndexOf(dropSortOrder.Items.FindByValue(strSortOrder))
 44:   End If
 45: End Sub

 

 

Sub dgrdSortOrders_DeleteCommand()イベントの処理

 

このイベントは、DataGridから削除ボタンをクリックしたときに発生します。このイベントでは、SortOrderDataTableからレコードを削除してListBoxに戻します。

 

52-53では、DataGridの先頭セルからレコードのIDを取得しています。DataGridの先頭セルには、BoundColumnSortOrderテーブルのIDをバインドしています。

 

233:             <asp:BoundColumn DataField="ID"
234:               Visible="False" ReadOnly="True" />

 

DataGridからレコードのIDを取得するには、以下のように記述することもできます。

 

Dim intID As Integer = Int32.Parse(e.Item.Cells(0).Text)

or

Dim intID As Integer = dgrdSortOrders.DataKeys(e.Item.ItemIndex)

 

54-55では、DataTableからDataViewを作成して、DataViewSortプロパティにIDを設定して並べ替えしています。行56では、DataViewFind()メソッドでレコードを検索しています。Find()メソッドの引数には、Sortプロパティに設定されているカラムの値を検索キーとして指定します。Find()メソッドからは、レコードのインデックス番号が返ります。

 

57-65If…End Ifでは、レコードが見つかったか調べています。レコードが見つかったときは、レコードを削除してListBoxに戻します。行58では、DataViewからDataRowViewを作成しています。DataRowViewには、検索したレコードが格納されます。行59-60では、DataRowViewからSortColumnSortFieldNameのカラム値を取得します。行61では、DataRowViewDelete()メソッドでレコードを削除します。

 

62では、ListBoxに削除したレコードを戻しています。ListBoxにアイテムを追加するには、ItemsコレクションのAdd()メソッドを使用します。Add()メソッドの引数には、ListItemを指定します。ListItem()の引数には、Text/Valueプロパティを指定します。

 

63では、最新のDataTableSession変数に保存します。行64では、BindDataGrid()を呼び出してDataGridをリフレッシュします。これで、DataGridからレコードが消去されてListBoxに追加されます。

 

 

51: Sub dgrdSortOrders_DeleteCommand(s As Object, e As DataGridCommandEventArgs)
 52:   Dim dgi As DataGridItem = e.Item
 53:   Dim intID As Integer = Int32.Parse(dgi.Cells(0).Text)
 54:   Dim dv As DataView = New DataView(mdt)
 55:   dv.Sort = "ID"
 56:   Dim intRowIndex As Integer = dv.Find(intID)
 57:   If intRowIndex <> -1 Then
 58:     Dim drv As DataRowView = dv(intRowIndex)
 59:     Dim strSortColumn As String = drv("SortColumn")
 60:     Dim strSortField As String = drv("SortFieldName")
 61:     drv.Delete
 62:     lstSortColumns.Items.Add( New ListItem(strSortColumn, strSortField) )
 63:     Session("SortOrder") = mdt
 64:     BindDataGrid()
 65:   End If
 66: End Sub

 

 

Sub dropSortOrder_SelectedIndexChanged()イベントの処理

 

このイベントは、DropDownListからアイテムを選択したときに発生します。このイベントでは、DropDownListから選択したアイテムをDataTableに反映します。

 

69-70では、DataGridItemの先頭セルからレコードのIDを取得しています。DropDownListOnSelectedIndexChangedイベントからDataGridItemを取得するには、NamingContainerを使用します。

 

Dim dgi As DataGridItem = CType(CType(s, Control).NamingContainer, DataGridItem)

 

変数sには、DropDownListのオブジェクトが格納されています。NamingContainerの代わりにParentプロパティを使用する方法もあります。

 

Dim dgi As DataGridItem = CType(CType(s, Control).Parent.Parent, DataGridItem)

 

71では、DataGridItemFindControl()メソッドでDropDownListを検索しています。行72では、DropDownListSelectedItem.Valueプロパティから、選択したアイテムのValue(Asc/Desc)を取得しています。

 

74-75では、DataTableからDataViewを作成して、DataViewSortプロパティにレコードのIDを設定して並べ替えています。行76では、DataViewFind()メソッドでレコードを検索しています。Find()メソッドの引数には、Sortプロパティに設定されているカラムの値を検索キーとして指定します。Find()からは、レコードのインデックス番号を返します。

 

77-81If…End Ifでは、レコードが見つかったか調べています。レコードが見つかったときは、レコードのSortOrderカラムにDropDownListから選択した値を設定して更新します。行80では、最新のDataTableSession変数に保存しています。

 

68: Sub dropSortOrder_SelectedIndexChanged(s As Object, e As EventArgs)
 69:   Dim dgi As DataGridItem = CType(CType(s, Control).NamingContainer, DataGridItem)
 70:   Dim intID As String = Int32.Parse(dgi.Cells(0).Text)
 71:   Dim dropSortOrder As DropDownList = CType(dgi.FindControl("dropSortOrder"), DropDownList)
 72:   Dim strSortOrder As String = dropSortOrder.SelectedItem.Value
 73:
 74:   Dim dv As DataView = New DataView(mdt)
 75:   dv.Sort = "ID"
 76:   Dim intRowIndex As Integer = dv.Find(intID)
 77:   If intRowIndex <> -1 Then
 78:     Dim drv As DataRowView = dv(intRowIndex)
 79:     drv("SortOrder") = strSortOrder
 80:     Session("SortOrder") = mdt
 81:   End If
 82: End Sub

 

 

Sub btnApply_Click()イベントの処理

 

このイベントは、適用ボタンをクリックしたときに発生します。このイベントでは、SortOrderDataTableからレコードを抽出してSQLORDER BY句を生成します。ここで生成したORDER BY句は、TextBox経由で親ウィンドウに渡します。

 

88-95For Each…Nextでは、DataTableRowsコレクションからDataRowを取得しています。行89-91If…End Ifでは、カラムが複数のときStringBuilderAppend()メソッドでコンマ(,)を追加しています。行92-94では、StringBuilderAppend()メソッドでカラム名と並べ替えオプション(Asc/Desc)を追加しています。

 

Ken Asc, CustomerID Desc, …..

 

98-103With…End Withでは、StringBuilderAppend()メソッドで、以下のJavaScriptを生成しています。

 

<script language='javascript'>

window.opener.frmMain.txtMessage.value = ' Sort Expression';

</script>

 

JavaScriptwindow.opener.frmMain.txtMessage.value=では、親ウィンドウのTextBoxに並べ替えするカラム(Sort Expression)を設定しています。ここで設定したSort Expressionは、親ウィンドウがDataGridを並べ替えるのに使用します。

 

104では、Page.RegisterClientScriptBlock()メソッドでJavaScriptを登録しています。ここで登録したJavaScriptは、Webページがロードされたときにクライアント側のブラウザから実行されます。

 

84: Sub btnApply_Click(s As Object, e As EventArgs)
 85:   Dim sbSortExpression As New StringBuilder()
 86:   Dim dr As DataRow
 87:

 88:   For Each dr In mdt.Rows
 89:     If sbSortExpression.Length > 0 Then
 90:       sbSortExpression.Append(", ")
 91:     End If
 92:     sbSortExpression.Append(dr("SortFieldName"))
 93:     sbSortExpression.Append(" ")
 94:     sbSortExpression.Append(dr("SortOrder"))
 95:   Next
 96:
 97:   Dim sbScript As New StringBuilder()
 98:   With sbScript
 99:     .Append("<script language='javascript'>" & vbCrLf)
100:     .Append(vbTab & "window.opener.frmMain.txtMessage.value = '" & _
101:       sbSortExpression.ToString() & "';" & vbCrLf)
102:     .Append("</" & "script>")
103:   End With
104:   RegisterClientScriptBlock("sort", sbScript.ToString)
105: End Sub

 

 

Sub BindListBox()の処理

 

このプロシージャでは、ListBoxに得意先テーブルのカラムを表示します。BindListBoxは、Page_Load()イベントから呼ばれます。

 

116-123With…End Withでは、ListBoxItemsコレクションのAdd()メソッドでアイテムを追加しています。Add()メソッドの引数には、ListItemを指定しています。ListItem()の引数には、Text/Valueプロパティを指定します。ここでは、Textプロパティにカラムヘッダ、Valueプロパティにカラム名を指定しています。

 

115: Sub BindListBox()
116:   With lstSortColumns
117:     .Items.Add(New ListItem("
得意先ID","CustomerID"))
118:     .Items.Add(New ListItem("
得意先名","CompanyKana"))
119:     .Items.Add(New ListItem("
担当者名","ContactName"))
120:     .Items.Add(New ListItem("
役職部署","ContactTitle"))
121:     .Items.Add(New ListItem("
電話番号","Phone"))
122:     .Items.Add(New ListItem("
都道府県","Ken"))
123:   End With             
124: End Sub

 

 

Sub BindDataGrid()の処理

 

このサブプロシージャでは、DataGridSortOrderDataTableをバインドします。BindDataGridは、btnAdd_Click()dgrdSortOrders_DeleteCommand()イベントから呼ばれます。

 

107: Sub BindDataGrid()
108:   With dgrdSortOrders
109:     .DataSource = mdt
110:     .DataKeyField = "ID"
111:     .DataBind()
112:   End With
113: End Sub

 

 

Function GetSequence()関数の処理

 

この関数は、並べ替え順のシーケンス番号を生成して返します。この関数は、DataGridTemplateColumnがバインドされるときに呼ばれます。

 

235:             <asp:TemplateColumn>
236:               <ItemTemplate>
237:                 <%#
GetSequence() %>
238:               </ItemTemplate>
240:             </asp:TemplateColumn>

 

GetSequence()は、1から始まるシーケンス番号を生成して返します。

 

126: Function GetSequence() As Integer
127:   mintSequence += 1
128:   Return mintSequence
129: End Function

 

 

Function CreateDataTable()関数の処理

 

この関数は、SortOrderDataTableを作成して返します。この関数は、Page_Load()イベントから呼ばれます。

 

132では、SortOrderDataTableを作成しています。行135-138では、DataTableIDのカラムを追加して自動採番されるようにオートインクレメント型の属性にしています。行139-141では、DataTableSortColumnSortFieldNameSortOrderのカラムを追加しています。行142では、DataTablePrimaryKeyプロパティにIDのカラムを設定しています。行143では、Session変数にDataTableを保存しています。行144では、戻り値としてDataTableを返しています。

 

 

131: Function CreateDataTable() As DataTable
132:   Dim dt As New DataTable("SortOrder")
133:   Dim dc As DataColumn
134:

135:   dc = dt.Columns.Add("ID", GetType(Integer))
136:   dc.AutoIncrement = True
137:   dc.AutoIncrementSeed = 1
138:   dc.AutoIncrementStep = 1
139:   dt.Columns.Add("SortColumn", GetType(String))
140:   dt.Columns.Add("SortFieldName", GetType(String))
141:   dt.Columns.Add("SortOrder", GetType(String))
142:   dt.PrimaryKey = New DataColumn() {dc}
143:   Session("SortOrder") = dt
144:   Return dt             
145: End Function

 

 

リスト  PopupSort.aspxのソースコード(コード編)

  1: <%@ Page language="vb" SmartNavigation="False" %>
  2: <%@ Import Namespace="System.Data" %>
  3: <%@ Import Namespace="System.Data.OleDb" %>
  4:
  5: <script language="vb" runat="server">
  6: Private mdt As DataTable
  7: Private mintSequence As Integer = 0
  8:
  9: Sub Page_Load()
 20: End Sub
 21:
 22: Sub btnAdd_Click(s As Object, e As EventArgs)
 33: End Sub
 34:
 35: Sub dgrdSortOrders_ItemDataBound(s As Object, e As DataGridItemEventArgs)
 45: End Sub
 46:
 47: Sub dgrdSortOrders_ItemCommand(s As Object, e As DataGridCommandEventArgs)
 49: End Sub
 50:
 51: Sub dgrdSortOrders_DeleteCommand(s As Object, e As DataGridCommandEventArgs)
 66: End Sub
 67:
 68: Sub dropSortOrder_SelectedIndexChanged(s As Object, e As EventArgs)
 82: End Sub
 83:
 84: Sub btnApply_Click(s As Object, e As EventArgs)
105: End Sub
106:
107: Sub BindDataGrid()
113: End Sub
114:
115: Sub BindListBox()
124: End Sub
125:
126: Function GetSequence() As Integer
129: End Function
130:
131: Function CreateDataTable() As DataTable
145: End Function
170: </script>

 

ASP.NET DataGrid2のホームへ戻る