ウィンドウ間でレコードの移動を連動させるサンプル

 

 

親ウィンドウ/子ウィンドウ間でレコードの移動を連動させるサンプル

 

このサンプルは、子ウィンドウから左右の矢印ボタンをクリックしてWebフォームに表示するレコードを移動することができます。子ウィンドウからレコードを移動すると、親ウィンドウのDataGridに表示されているカーソルも連動して移動します。

 

更新ボタンをクリックすると、編集したレコードをDataTableに反映します。さらに、子ウィンドウから編集したレコードを親ウィンドウにも反映します。このサンプルでは、更新ボタンをクリックしたときDataTable上のレコードを更新しますが、データベースには反映していません。

 

◆プログラムPopupEmployee.aspxのポイント

 

¶ポイント1 ページ内およびページ間でデータを渡すには

 

このサンプルでは、ページ内でデータを渡すときは、ViewState()を使用しています。ViewState()に保存されたデータは、HTML<input>タグに格納されて復元されます。ページ間でデータを渡すときは、QueryStringSession変数を使用しています。ページ間でデータを渡すには、この他にServer.Transfer()Response.Cookies()

Request.Cookies()などを使用する方法もあります。

 

 

¶ポイント2 Select()メソッドとFind()メソッドの使い分け

 

DataTableからフィルタ条件を設定してレコードを絞り込むときは、Select()メソッドを使用します。Select()には、filterExpressinsortrecordStateなどの引数を指定することができます。これらの引数は、オプションですから必要な場合のみ指定します。

 

Select(filterExpressionsortrecordStates)

 

引数filterExpressionには、SQLWHERE句と同じ形式で指定します。引数sortには、SQLORDER BY句の形式で、並べ替えするカラムと昇順/降順のオプションを指定します。

 

EmployeeID Asc

EmployeeID Desc

 

引数recordStatesには、レコードの状態を指定して絞り込むことができます。このサンプルでは、Select()filterExpressionsortの引数を指定してレコードを絞り込んでいます。

 

DataTable.Select("EmployeeID >= 999", "EmployeeID")

DataTable.Select("EmployeeID <= 999", "EmployeeID")

 

DataTableから主キーを指定して特定のレコードを検索するときは、RowsコレクションのFind()メソッドを使用します。このサンプルでは、DataGridから選択したレコードを表示するときに、Find()メソッドを使用しています。

 

Find()を使用するときは、DataTablePrimaryKeyプロパティに主キーのカラム名を設定する必要があります。

 

DataTable.PrimaryKey = New DataColumn() {DataTable.Columns("EmployeeID")}

DataTable.Rows.Find(999)

 

 

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

 

DataGridEmployee.aspxHTML編について解説します。なお、DataGridEmployee.aspxは、第88-1で解説しているサンプルと類似していますので、ここでは相違点を中心に説明します。

 

153-160ImageButtonでは、レコード編集ボタンを定義しています。このボタンには、OnCommandイベントを登録しています。このイベントでは、子ウィンドウを開きます。行161-167LabelTextBoxでは、レコード件数を表示しています。

 

180-247では、DataGridを定義しています。このDataGridでは、AutoGenerateColumnsプロパティにFalseを設定してカラムの自動生成機能を抑止しています。行194-246<Columns>…</Columns>では、TemplateColumnBoundColumnを定義して、社員テーブルをバインドしています。

 

255-260では、子ウィンドウから親ウィンドウにメッセージを渡すTextBoxを定義しています。このTextBoxは、メッセージを表示する役割と子ウィンドウから親ウィンドウをポストバックする重要な役割をします。行265-268では、Buttonを定義しています。このButtonには、OnClickイベントが登録されています。このイベントは、子ウィンドウから親ウィンドウをポストバックしたときに実行されます。なお、このButtonVisibleプロパティには、Falseが設定されていますのでWebフォームには表示されません。

 

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

134: <html>
140: <body>
149: <form id="frmMain" runat="server">
153: <asp:ImageButton id="ibtnUpdate" runat="server"
154:   CommandName="update"
155:   OnCommand="ibtnUpdate_Command"
156:   ImageUrl="../img/update.gif"
158:   CssClass="imageButton"
160:   Enabled="True" />
161: <asp:Label id="lblRows" runat="server"
162:   Text="
件数"
163:   />
164: <asp:TextBox id="txtRows" runat="server"
166:   Columns="3"
167:   ReadOnly="True" />
180: <asp:DataGrid id="dgrdEmployees" runat="server"
181:   AutoGenerateColumns="False"
182:   OnItemCommand="dgrdEmployees_ItemCommand"
183:   OnItemDataBound="dgrdEmployees_ItemDataBound"
189:   EnableViewState="True">
194:   <Columns>
195:     <asp:TemplateColumn
196:       HeaderText="<div class='dgrdHeaderBox'>1</div>">
197:       <ItemTemplate>
198:         <asp:LinkButton id="lbtnSelect" runat="server"
199:           CommandName="Select"
200:           Text="<div class='dgrdItemArrow'>4</div>"

201:           Visible="True" />
202:       </ItemTemplate>
205:     </asp:TemplateColumn>
206:     <asp:BoundColumn ItemStyle-Width="20"
207:       HeaderText="<div class='dgrdHeader'>ID</div>"
208:       DataField="EmployeeID">
210:     </asp:BoundColumn>
        
・・・

246:   </Columns>
247: </asp:DataGrid>
255: <asp:TextBox id="txtMessage" runat="server"
258:   Columns="140"
259:   Visible="True"
260:   ReadOnly="True" />
265: <asp:Button id="btnRefresh" runat="server"
266:   Text="Hidden"
267:   Visible="False"
268:   OnClick="btnRefresh_Click" />
269: </form>
270: </body>
270: </html>

 

 

 

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

 

 

Sub Page_Load()イベントの処理

 

このイベントは、DataGridEmployee.aspxがロードされたときに実行されます。このイベントでは、DataGridに社員テーブルをバインドして表示します。

 

10では、メッセージを表示するTextBoxにクライアント側で動作するonPropertyChangeイベントを登録しています。TextBoxにクライアント側で動作するイベントを登録するには、AttributesコレクションのAdd()メソッドを使用します。Add()メソッドの引数には、イベント名とイベント処理を記述します。イベント処理には、Page.GetPastBackEventReference()メソッドで生成されたJavaScriptを埋め込みます。このメソッドは、WebページをポストバックするJavaScriptを生成します。Page_Loadイベントに、このステートメントを追加することにより、子ウィンドウから親ウィンドウにメッセージを渡してポストバックさせることが可能になります。

 

11-20If…Else…End Ifでは、ページが最初にロードされたか調べています。最初にロードされたときは、ViewState()の社員ID0を設定して初期化します。さらに、BindDataGrid()を呼び出して、DataGridに社員テーブルをバインドします。

 

ページがポストバックされたときは、ViewState()に保存されている社員IDを取得します。ViewState()には、DataGridから選択したレコードの社員IDが保存されています。次に、Session変数に保存されているDataTableを取得します。Session変数にDataTableが保存されていないときは、BindDataGrid()を呼びます。

 

 

  9: Sub Page_Load()
 10:   txtMessage.Attributes.Add("OnPropertyChange", GetPostBackEventReference(btnRefresh))
 11:   If Not IsPostBack Then
 12:     ViewState("EmployeeID") = mintEmployeeID
 13:     BindDataGrid()
 14:   Else
 15:     mintEmployeeID = ViewState("EmployeeID")
 16:     mdt = CType(Session("Employees"), DataTable)
 17:     If mdt Is Nothing Then
 18:       BindDataGrid()
 19:     End If
 20:   End If
 21: End Sub

 

 

Sub dgrdEmployees_ItemDataBound()イベントの処理

 

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

 

56: Sub dgrdEmployees_ItemDataBound(s As Object, e As DataGridItemEventArgs)
 57:   Dim lit As ListItemType = e.Item.ItemType
 58:
 59:   If lit = ListItemType.Item OrElse _
 60:     lit = ListItemType.AlternatingItem OrElse _
 61:     lit = ListItemType.SelectedItem Then
 62:     Dim lbtn As LinkButton = CType(e.Item.FindControl("lbtnSelect"), LinkButton)
 63:     e.Item.Attributes("onClick") = GetPostBackClientHyperlink(lbtn, "")
 64:     e.Item.Style("cursor") = "hand"
 65:   End If
 66: End Sub

 

 

Sub dgrdEmployees_ItemCommand()イベントの処理

 

このイベントは、DataGridからアイテム(DataGridItem)を選択したときに発生します。このイベントでは、選択したアイテムの社員IDを取得してViewState()に保存します。選択したアイテムの社員IDは、DataGridDataKeysコレクションから取得します。DataKeysコレクションの引数には、アイテムのインデックス番号を指定します。

 

68: Sub dgrdEmployees_ItemCommand(s As Object, e As DataGridCommandEventArgs)
 69:   If e.CommandName = "Select" Then
 70:     mintEmployeeID = dgrdEmployees.DataKeys(e.Item.ItemIndex)
 71:     ViewState("EmployeeID") = mintEmployeeID
 72:   End If
 73: End Sub

 

 

Sub ibtnUpdate_Command()イベントの処理

 

このイベントは、レコード編集ボタンをクリックしたときに発生します。このイベントでは、InsertScripBlock()を呼び出して子ウィンドウを開きます。InsertScriptBlockの引数には、編集するレコードの社員IDを指定します。

 

75: Sub ibtnUpdate_Command(s As Object, e As CommandEventArgs)
 76:   InsertScriptBlock(mintEmployeeID)
 77: End Sub

 

 

Sub btnRefresh_Click()イベントの処理

 

このイベントは、子ウィンドウから親ウィンドウのTextBoxを書き換えたときに発生します。このTextBoxには、クライアント側で動作するonPropertyChangeイベントが登録されています。子ウィンドウからこのTextBoxを書き換えると、onPropertyChangeイベントが発生して親ウィンドウをポストバックします。親ウィンドウがポストバックされると、btnRefresh_Clickが実行されます。btnRedresh_Clickイベントでは、Session変数からカレントの社員IDを取得してDataGridの対応するアイテムを選択した状態にします。

 

ところで、btnRefresh_Clickイベントの前にPage_Loadイベントが発生していることに注意してください。つまり、Page_Loadイベントの初期化処理がすでに実行された状態でこのイベントに制御が渡ります。

 

24-28With…End Withでは、DataGridDataTableをバインドしてリフレッシュします。DataTableには、子ウィンドウで編集したレコードが反映されていますので、DataGridには最新のデータが表示されます。

 

31-38では、Session変数に社員IDが保存されているか確認しています。社員IDが保存されていないときは、DataGridのアイテムを選択しないで戻ります。

 

42-46For…Nextでは、DataTableRowsコレクションからDataRowを取り出して、レコードの社員IDを検索しています。社員IDが見つかったときは、ループを終了してDataGridSelectedIndexプロパティに検索したレコードのインデックス番号を設定します。これで、Session変数に保存されていた社員IDのレコードが選択された状態になります。

 

48-49では、ViewState()にカレントの社員IDを保存します。

 

 

23: Sub btnRefresh_Click(s As Object, e As EventArgs)
 24:   With dgrdEmployees
 25:     .DataSource = mdt
 26:     .DataKeyField = "EmployeeID"
 27:     .DataBind()
 28:   End With
 29:   txtRows.Text = mdt.Rows.Count.ToString()
 30:
 31:   If Session("EmployeeID") Is Nothing Then
 32:     Exit Sub
 33:   End If
 34:
 35:   Dim intEmployeeID As Integer = CType(Session("EmployeeID"), Integer)
 36:   If intEmployeeID = 0 Then
 37:     Exit Sub
 38:   End If
 39:
 40:   Dim dr As DataRow
 41:   Dim intRowIndex As Integer
 42:   For intRowIndex = 0 To mdt.Rows.Count - 1
 43:     If mdt.Rows(intRowIndex)("EmployeeID") = intEmployeeID Then
 44:       Exit For
 45:     End If
 46:   Next
 47:   dgrdEmployees.SelectedIndex = intRowIndex
 48:   mintEmployeeID = intEmployeeID
 49:   ViewState("EmployeeID") = mintEmployeeID
 50: End Sub

 

 

Sub InsertScriptBlock()の処理

 

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

 

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

 

<script language='javascript'>
window.open('PopupEmployee.aspx?id=999','_blank','features');

</script>

 

JavaScriptwindow.open()メソッドは、新規ウィンドウを開きます。Open()メソッドの引数には、urltargetfeaturesを指定します。urlには、新規ウィンドウに表示するファイルPopupEmployee.aspxを指定します。なお、このurlには、QueryStringに編集するレコードの社員IDを指定しています。

 

PopupEmployee.aspx?id=999

 

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

 

 

98: Sub InsertScriptBlock(intEmployeeID As Integer)
 99:   Dim strFeatures As String = "height=260,width=360,left=10,top=10," & _
100:     "location=no,menubar=no,resizable=yes,scrollbars=no," & _
101:     "status=no,titlebar=yes,toolbar=no"
102:   Dim sbScript As New StringBuilder()
103:   With sbScript
104:     .Append("<script language='javascript'>" & vbCrLf)
105:     .Append(vbTab & "window.open('PopupEmployee.aspx?id=" &

intEmployeeID.ToString & "','_blank','" & strFeatures & "');" & vbCrLf)
106:     .Append("</" & "script>")
107:   End With             
108:   RegisterClientScriptBlock("openWindow", sbScript.ToString)
109: End Sub

 

 

Sub BindDataGrid()の処理

 

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

 

80では、社員テーブルからレコードを抽出するSQLを生成しています。SELECTステートメントには、Top 10のオプションを指定していますので、社員テーブルから10件のレコードが抽出されます。行81では、CreateDataSet()関数を呼び出して、社員テーブルのDataSetを作成しています。

 

83では、DataSetTablesコレクションから社員テーブルのDataTableを作成しています。行84では、DataTablePrimaryKeyプロパティに社員テーブルの主キー(社員ID)のカラム名を設定しています。主キーを設定することにより、DataTableRowsコレクションのFind()メソッドが使用できるようになります。

 

86-93With…End Withでは、DataSetDataTableをバインドしています。行94では、DataTableRowsコレクションのCountプロパティからレコード件数を取得してTextBoxに設定しています。行95では、Session変数にDataTableを保存しています。ここで保存したDataTableは、ポストバックされた時とサブプログラムで使用します。

 

 

79: Sub BindDataGrid()
 80:   Dim strSQL As String = "Select top 10 * From Employees"
 81:   Dim ds AS DataSet = CreateDataSet(strSQL)
 82:
 83:   mdt = ds.Tables(0)
 84:   mdt.PrimaryKey = New DataColumn() {mdt.Columns("EmployeeID")}
 85:
 86:   With dgrdEmployees
 87:     .DataSource = mdt
 88:     .DataKeyField = "EmployeeID"
 89:     .DataBind()
 90:     .SelectedIndex = 0
 91:     mintEmployeeID = .DataKeys(0)
 92:     ViewState("EmployeeID") = mintEmployeeID

 93:   End With
 94:   txtRows.Text = mdt.Rows.Count.ToString()
 95:   Session("Employees") = mdt
 96: End Sub

 

 

Function CreateDataSet()関数の処理

 

この関数は、データベースからレコードを抽出してDataSetを作成して返します。CreateDataSetは、BindDataGrid()から呼ばれます。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" />

 

 

121: Function CreateDataSet(strSQL As String, _
122:   Optional strConnectionString As String = "conStringAccNw") As DataSet
123:   Dim con As New OleDbConnection( _
124:     ConfigurationSettings.AppSettings(strConnectionString))
125:   Dim da As New OleDbDataAdapter(strSQL, con)
126:   Dim ds As New DataSet()
127:
128:   da.Fill(ds)
129:   Return ds
130: End Function

 

 

リスト DataGridEmployee.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 mintEmployeeID As Integer = 0
  8:
  9: Sub Page_Load()
 21: End Sub
 22:
 23: Sub btnRefresh_Click(s As Object, e As EventArgs)
 50: End Sub
 51:
 56: Sub dgrdEmployees_ItemDataBound(s As Object, e As DataGridItemEventArgs)
 66: End Sub
 67:
 68: Sub dgrdEmployees_ItemCommand(s As Object, e As DataGridCommandEventArgs)
 73: End Sub
 74:
 75: Sub ibtnUpdate_Command(s As Object, e As CommandEventArgs)
 77: End Sub
 78:
 79: Sub BindDataGrid()
 96: End Sub
 97:
 98: Sub InsertScriptBlock(intEmployeeID As Integer)
109: End Sub
110:
121: Function CreateDataSet(strSQL As String, _
122:   Optional strConnectionString As String = "conStringAccNw") As DataSet
130: End Function
132: </script>

 

 

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

 

PopupEmployee.aspxHTML編を解説します。このサブプログラムでは、親ウィンドウのDataGridから選択したレコードをWebページに表示して編集することができます。

 

236-245LabelTextBoxでは、社員テーブルの社員IDを表示しています。TextBoxReadOnlyプロパティには、Trueを設定して読み込み専用にしています。

 

251-258LabelTextBoxでは、氏名を表示しています。このTextBoxには、RequiredFieldValidatorを定義してエラーチェックしています。後続するLabelTextBoxでは、支社、入社日、備考を表示しています。支社、入社日、備考のTextBoxの右側にはImageButtonを定義していますが、このサンプルでは使用不可にしています。これらの使用不可のImageButtonには、CSSfilterプロパティにalpha(opacity=20)を設定してイメージをディミング(薄くぼんやり見えるように)しています。

 

.imageOff {

cursor:help;

filter: alpha(opacity=20); 

}

 

<asp:ImageButton runat="server"

   Title="Disabled!"     

   CssClass="imageOff"

   Enabled="False"

   />

 

335-352では、ImageButtonでレコード移動ボタンを定義しています。これらのImageButtonには、OnClickイベントが登録されています。OnClickイベントでは、Webページに表示されているレコードを前後に移動します。行353-360LabelDropDownListでは、エディタの種類を定義していますが、このサンプルでは使用不可にしています。

 

ImageButtonでレコード移動ボタンを表示した例

 

363-370では、「更新」と「閉じる」のButtonを定義しています。更新ボタンには、OnClickイベントが登録されています。OnClickイベントでは、Webページから編集したレコードをDataTableに反映します。閉じるボタンには、OnClickイベントが登録されていませんが、ランタイム時にクライアント側で動作するonClickイベントを登録します。クライアント側で動作するonClickイベントでは、子ウィンドウを閉じます。

 

図 「更新」と「閉じる」ボタンを表示した例

 

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

219: <html>
225: <body>
226: <form id="frmPopupEmployee" runat="server">
236: <asp:Label id="lblEmployeeID" runat="server"
238:   Text="ID" />
241: <asp:TextBox id="txtEmployeeID" runat="server"
243:   Text="auto"
244:   Columns="4"
245:   ReadOnly="True" />

251: <asp:Label id="lblName" runat="server"
253:   Text="
氏名" />
256: <asp:TextBox id="txtName" runat="server"
258:   Columns="20" />
259: <asp:RequiredFieldValidator runat="server"
260:   ControlToValidate="txtName"
261:   ErrorMessage="*" />
     
・・・

335: <asp:ImageButton id="ibtnPrev" runat="server"
336:   CausesValidation="False"
337:   CommandName="prev"
338:   ImageUrl="../img/prev.gif"
339:   Title="Prev"
340:   CssClass="imageButton"
341:   Enabed="True"
342:   ImageAlign="Middle"
343:   OnClick="ibtnPrev_Click" />
344: <asp:ImageButton id="ibtnNext" runat="server"
345:   CausesValidation="False"
346:   CommandName="next"
347:   ImageUrl="../img/next.gif"
348:   Title="Next"
349:   CssClass="imageButton"
350:   Enabled="True"
351:   ImageAlign="Middle"
352:   OnClick="ibtnNext_Click" />
353: <asp:Label id="lblEditor" runat="server"
354:   Text="
エディタ" Font-Name="Tahoma" Font-Size="9pt"
355:   CssClass="statusRow" />
356: <asp:DropDownList id="dropEditor" runat="server"
357:   CssClass="statusRow"
358:   Enabled="False">
359:   <asp:ListItem Text="HTML" />
360: </asp:DropDownList>

363: <asp:Button id="btnUpdate" runat="server"
364:   Text="
更新"
366:   OnClick="btnUpdate_Click" />
367: <asp:Button id="btnClose" runat="server"
368:   CausesValidation="False"
369:   Text="
閉じる"
370:   Style="vertical-align:middle" />
3376: </form>
377: </body>
377: </html>

 

 

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

 

PopupEmployee.aspxでは、レコード移動ボタンをクリックしたときWebページに表示するレコードを移動します。

 

Sub Page_Load()イベントの処理

 

このイベントは、PopupEmployee.aspxがロードされたときに実行されます。このイベントでは、Webページに親ウィンドウから選択したレコードを表示します。

 

9では、Session変数に保存されている社員テーブルのDataTableを取得しています。行18-22If…End Ifでは、ページが最初にロードされたか調べています。ページが最初にロードされたときは、閉じるボタンにクライアント側で動作するonClickイベントを登録しています。このonClickイベントでは、JavaScriptwindow.close()メソッドで子ウィンドウを閉じます。次に、GetRecord()を呼び出して親ウィンドウのDataGridから選択したレコードをTextBoxに表示します。

 

 

  8: Sub Page_Load()
  9:   mdt = CType(Session("Employees"), DataTable)
 18:   If Not IsPostBack Then
 19:     btnClose.Attributes.Add("onClick", "window.close();")
 21:     GetRecord()
 22:   End If
 23: End Sub

 

 

Sub ibtnPrev_Click()イベントの処理

 

このイベントは、Webページから左矢印のレコード移動ボタンをクリックしたときに発生します。このイベントは、現在表示されている1つ前のレコードを表示します。

 

59では、TextBoxTextプロパティから社員IDを取得しています。行60-61では、DataTableSelect()メソッドでフィルタ条件に一致するレコードを抽出しています。Select()メソッドの引数には、フィルタ条件と並べ替えするカラムを指定します。Select()メソッドの戻り値としてDataRowが配列として返されます。

 

Dim arrRows As DataRow() = mdt.Select("EmployeeID <= 999","EmployeeID")

 

64-78If…Else…End Ifでは、Select()メソッドから返されたレコード件数を調べています。レコードが1件以上返されたときは、カレント-1のレコードを表示します。レコードが1件のときは、カレントのレコードを再度表示します。

 

65では、カレント-1のレコードを配列から取り出してDataRowを作成しています。行66では、DisplayRecord()を呼び出してDataRowTextBoxに表示します。DisplayRecord()の引数には、DataRowを指定します。行67-70では、移動ボタンを使用可能にしています。

 

72では、配列からカレントのレコードを取り出してDataRowを作成しています。行73では、DisplayRecord()を呼び出してカレントのレコードをTextBoxに表示します。行74-77では、左矢印のボタンを使用不可、右矢印のボタンを使用可にしています。

 

79では、Session変数に移動ボタンクリック後の最新の社員IDを保存します。ここで保存したSession変数は、親ウィンドウがポストバックされたときに参照します。つまり、子ウィンドウから親ウィンドウに社員IDを渡す目的で使用しています。行80では、PostBackMain()を呼び出して親ウィンドウをポストバックします。PostBackMain()の引数には、親ウィンドウのTextBoxに表示するメッセージを指定します。親ウィンドウがポストバックされると、DataGridには子ウィンドウのレコードが選択された状態で表示されます。

 

58: Sub ibtnPrev_Click(s As Object, e As ImageClickEventArgs)
 59:   Dim strEmployeeID As String = txtEmployeeID.Text.Trim()
 60:   Dim strCriteria As String = "EmployeeID <= " & strEmployeeID
 61:   Dim arrRows As DataRow() = mdt.Select(strCriteria,"EmployeeID")
 62:   Dim dr As DataRow
 63:
 64:   If arrRows.Length > 1 Then
 65:     dr = arrRows(arrRows.Length-2)
 66:     DisplayRecord(dr)
 67:     ibtnPrev.ImageUrl = "../img/prev.gif"
 68:     ibtnPrev.Enabled = True
 69:     ibtnNext.ImageUrl = "../img/next.gif"
 70:     ibtnNext.Enabled = True             
 71:   Else
 72:     dr = arrRows(0)
 73:     DisplayRecord(dr)
 74:     ibtnPrev.ImageUrl = "../img/prevOff.gif"
 75:     ibtnPrev.Enabled = False
 76:     ibtnNext.ImageUrl = "../img/next.gif"
 77:     ibtnNext.Enabled = True
 78:   End If
 79:   Session("EmployeeID") = dr("EmployeeID")
 80:   PostBackMain("
上位方向に移動...")
 81: End Sub

 

 

Sub ibtnNext_Click()イベントの処理

 

このイベントは、Webページから右矢印のレコード移動ボタンをクリックしたときに発生します。このイベントは、現在表示されている次のレコードを表示します。

 

84では、TextBoxTextプロパティから社員IDを取得しています。行85-86では、DataTableSelect()メソッドでフィルタ条件に一致するレコードを抽出しています。Select()メソッドの戻り値としてDataRowが配列として返されます。

 

Dim arrRows As DataRow() = mdt.Select("EmployeeID >= 999","EmployeeID")

 

89-103If…Else…End Ifでは、Select()メソッドから返されたレコード件数を調べています。レコードが1件以上返されたときは、カレント+1のレコードを表示します。レコードが1件のときは、カレントのレコードを再度表示します。カレントレコードが最終レコード以外のときは、双方の移動ボタンを使用可能にします。カレントレコードが最終レコードのときは、左矢印ボタンを使用可、右矢印ボタンを使用不可にします。

 

104では、Session変数に移動ボタンクリック後の最新の社員IDを保存します。行105では、PostBackMain()を呼び出して親ウィンドウをポストバックさせます。PostBackMain()の引数には、親ウィンドウのTextBoxに表示するメッセージを指定します。親ウィンドウがポストバックされると、DataGridには子ウィンドウのレコードが選択された状態で表示されます。

 

 

83: Sub ibtnNext_Click(s As Object, e As ImageClickEventArgs)
 84:   Dim strEmployeeID As String = txtEmployeeID.Text.Trim()
 85:   Dim strCriteria As String = "EmployeeID >= " & strEmployeeID
 86:   Dim arrRows As DataRow() = mdt.Select(strCriteria,"EmployeeID")
 87:   Dim dr As DataRow
 88:
 89:   If arrRows.Length > 1 Then
 90:     dr = arrRows(1)
 91:     DisplayRecord(dr)
 92:     ibtnNext.ImageUrl = "../img/next.gif"
 93:     ibtnNext.Enabled = True
 94:     ibtnPrev.ImageUrl = "../img/prev.gif"
 95:     ibtnPrev.Enabled = True
 96:   Else
 97:     dr = arrRows(0)
 98:     DisplayRecord(dr)
 99:     ibtnNext.ImageUrl = "../img/nextOff.gif"
100:     ibtnNext.Enabled = False
101:     ibtnPrev.ImageUrl = "../img/prev.gif"
102:     ibtnPrev.Enabled = True
103:   End If
104:   Session("EmployeeID") = dr("EmployeeID")
105:   PostBackMain("
下位方向に移動...")
106: End Sub

 

 

Sub PostBackMain()の処理

 

このサブプロシージャでは、親ウィンドウをポストバックするJavaScriptを生成して登録します。PostBackMainは、ibtnPrev_Click()ibtnNext_Click()イベントから呼ばれます。

 

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

 

<script language='javascript'>
window.opener.frmMain.txtMessage.value = 'message';

</script>

 

JavaScriptwindow.opener.frmMain.txtMessage.value =では、親ウィンドウのTextBoxに「message」を設定して書き換えています。このTextBoxには、クライアント側で動作するonPropertyChange()イベントが登録されています。TextBoxを書き換えると、このイベントが実行されて親ウィンドウがポストバックされます。親ウィンドウがポストバックされると、Webサーバ側でbtnRefresh_Click()イベントが実行されます。

 

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

 

 

132: Sub PostBackMain(strMessage As String)
133:   Dim sbScript As New StringBuilder()
134:   With sbScript
135:     .Append("<script language='javascript'>" & vbCrLf)
136:     .Append(vbTab & "window.opener.frmMain.txtMessage.value = '" & _
137:       strMessage & "';" & vbCrLf)
138:     .Append("</" & "script>")
139:   End With
140:   RegisterClientScriptBlock("insertScript", sbScript.ToString)
141: End Sub

 

 

Sub GetRecord()の処理

 

このサブプロシージャでは、親ウィンドウのDataGridから選択したレコードをTextBoxに表示します。GetRecord()は、Page_Loadイベントから呼ばれます。

 

144では、QueryStringから社員IDを取得しています。

 

PopupEmployee.aspx?id=999

Request.QueryString("id") è 999

 

145では、DataTableRowsコレクションのFind()メソッドでレコードを検索しています。Find()メソッドの引数には、主キー(社員ID)のカラム値を指定します。Find()メソッドからはDataRowが返されます。

 

147では、DisplayRecord()を呼び出して検索したレコードをTextBoxに表示します。DisplayRecord()の引数には、DataRowを指定します。

 

148では、SetButtons()を呼び出して移動ボタンを使用可、または使用不可にしています。カレントレコードが、先頭レコードのときは左矢印ボタンが使用不可になり、最終レコードのときは右矢印ボタンが使用不可になります。

 

143: Sub GetRecord()
144:   Dim intEmployeeID As Integer = Int32.Parse( Request.QueryString("id") )
145:   Dim dr As DataRow = mdt.Rows.Find(intEmployeeID)
146:
147:   DisplayRecord(dr)
148:   SetButtons()
149: End Sub

 

 

Sub DisplayRecord()の処理

 

このサブプロシージャでは、レコードの内容をTextBoxに表示します。DisplayRecordは、ibtnPrev_Click()ibtnNext_Click()GetRecord()から呼ばれます。

 

152-165If…Else…End Ifでは、DataRowにレコードが格納されているか調べています。レコードが格納されているときは、DataRowからカラム値を取得してTextBoxに設定します。レコードが格納されていないときは、TextBoxに空白を設定します。

 

151: Sub DisplayRecord(dr As DataRow)
152:   If Not (dr Is Nothing) Then
153:     txtEmployeeID.Text = dr("EmployeeID")
154:     txtName.Text = dr("Name")
155:     txtBranch.Text = dr("Branch")
156:     txtHireDate.Text = CType(dr("HireDate"), DateTime).ToString("d")
157:     txtNotes.Text = dr("Notes")
159:   Else
160:     txtEmployeeID.Text = String.Empty
161:     txtName.Text = String.Empty
162:     txtBranch.Text = String.Empty
163:     txtHireDate.Text = String.Empty
164:     txtNotes.Text = String.Empty
165:   End If
166: End Sub

 

 

Sub SetButtons()の処理

 

このサブプロシージャでは、レコード移動ボタンを使用可、または使用不可の状態に切り替えます。SetButtonsは、GetRecord()から呼ばれます。

 

169-179If…Else…End Ifでは、DataTableのレコード件数を調べています。レコード件数が1のときは、双方のレコード移動ボタンを使用不可の状態にします。レコード件数が1以外のときは、双方のボタンを使用可能状態にします。

 

168: Sub SetButtons()
169:   If mdt.Rows.Count = 1 Then
170:     ibtnPrev.ImageUrl = "../img/prevoff.gif"
171:     ibtnNext.ImageUrl = "../img/nextoff.gif"
172:     ibtnPrev.Enabled = False
173:     ibtnNext.Enabled = False
174:   Else
175:     ibtnPrev.ImageUrl = "../img/prev.gif"
176:     ibtnNext.ImageUrl = "../img/next.gif"
177:     ibtnPrev.Enabled = True
178:     ibtnNext.Enabled = True
179:   End If
180: End Sub

 

 

 

リスト PopupEmployee.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:
  8: Sub Page_Load()
 23: End Sub
 24:
 58: Sub ibtnPrev_Click(s As Object, e As ImageClickEventArgs)
 81: End Sub
 82:
 83: Sub ibtnNext_Click(s As Object, e As ImageClickEventArgs)
106: End Sub
107:
132: Sub PostBackMain(strMessage As String)
141: End Sub
142:
143: Sub GetRecord()
149: End Sub
150:
151: Sub DisplayRecord(dr As DataRow)
166: End Sub
167:
168: Sub SetButtons()
180: End Sub
217: </script>

 

ASP.NET DataGrid3のホームへ戻る