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

図 親ウィンドウ/子ウィンドウ間でレコードの移動を連動させるサンプル
このサンプルは、子ウィンドウから左右の矢印ボタン
、
をクリックしてWebフォームに表示するレコードを移動することができます。子ウィンドウからレコードを移動すると、親ウィンドウのDataGridに表示されているカーソルも連動して移動します。
更新ボタンをクリックすると、編集したレコードをDataTableに反映します。さらに、子ウィンドウから編集したレコードを親ウィンドウにも反映します。このサンプルでは、更新ボタンをクリックしたときDataTable上のレコードを更新しますが、データベースには反映していません。
◆プログラムPopupEmployee.aspxのポイント
¶ポイント1 ページ内およびページ間でデータを渡すには
このサンプルでは、ページ内でデータを渡すときは、Vie
Request.Cookies()などを使用する方法もあります。
¶ポイント2 Select()メソッドとFind()メソッドの使い分け
DataTableからフィルタ条件を設定してレコードを絞り込むときは、Select()メソッドを使用します。Select()には、filterExpressin、sort、recordStateなどの引数を指定することができます。これらの引数は、オプションですから必要な場合のみ指定します。
Select(filterExpression、sort、recordStates)
引数filterExpressionには、SQLのWHERE句と同じ形式で指定します。引数sortには、SQLのORDER BY句の形式で、並べ替えするカラムと昇順/降順のオプションを指定します。
EmployeeID Asc
EmployeeID Desc
引数recordStatesには、レコードの状態を指定して絞り込むことができます。このサンプルでは、Select()にfilterExpressionとsortの引数を指定してレコードを絞り込んでいます。
DataTable.Select("EmployeeID >= 999", "EmployeeID")
DataTable.Select("EmployeeID <= 999", "EmployeeID")
DataTableから主キーを指定して特定のレコードを検索するときは、Ro
Find()を使用するときは、DataTableのPrimaryKeyプロパティに主キーのカラム名を設定する必要があります。
DataTable.PrimaryKey = New DataColumn() {DataTable.Columns("EmployeeID")}
DataTable.Ro
◆メインプログラムDataGridEmployee.aspxの解説(HTML編)
DataGridEmployee.aspxのHTML編について解説します。なお、DataGridEmployee.aspxは、第8章8-1で解説しているサンプルと類似していますので、ここでは相違点を中心に説明します。
行153-160のImageButtonでは、レコード編集ボタンを定義しています。このボタンには、OnCommandイベントを登録しています。このイベントでは、子ウィンドウを開きます。行161-167のLabelとTextBoxでは、レコード件数を表示しています。
行180-247では、DataGridを定義しています。このDataGridでは、AutoGenerateColumnsプロパティにFalseを設定してカラムの自動生成機能を抑止しています。行194-246の<Columns>…</Columns>では、TemplateColumnとBoundColumnを定義して、社員テーブルをバインドしています。
行255-260では、子ウィンドウから親ウィンドウにメッセージを渡すTextBoxを定義しています。このTextBoxは、メッセージを表示する役割と子ウィンドウから親ウィンドウをポストバックする重要な役割をします。行265-268では、Buttonを定義しています。このButtonには、OnClickイベントが登録されています。このイベントは、子ウィンドウから親ウィンドウをポストバックしたときに実行されます。なお、このButtonのVisibleプロパティには、Falseが設定されていますのでWebフォームには表示されません。
リスト DataGridEmployee.aspxのソースコード(HTML編)
|
134: <html>
201:
Visible="True" />
246: </Columns> |
◆メインプログラムDataGridEmployee.aspxの解説(コード編)
Sub Page_Load()イベントの処理
このイベントは、DataGridEmployee.aspxがロードされたときに実行されます。このイベントでは、DataGridに社員テーブルをバインドして表示します。
行10では、メッセージを表示するTextBoxにクライアント側で動作するonPropertyChangeイベントを登録しています。TextBoxにクライアント側で動作するイベントを登録するには、AttributesコレクションのAdd()メソッドを使用します。Add()メソッドの引数には、イベント名とイベント処理を記述します。イベント処理には、Page.GetPastBackEventReference()メソッドで生成されたJavaScriptを埋め込みます。このメソッドは、WebページをポストバックするJavaScriptを生成します。Page_Loadイベントに、このステートメントを追加することにより、子ウィンドウから親ウィンドウにメッセージを渡してポストバックさせることが可能になります。
行11-20のIf…Else…End Ifでは、ページが最初にロードされたか調べています。最初にロードされたときは、Vie
ページがポストバックされたときは、Vie
|
9: Sub Page_Load() |
Sub dgrdEmployees_ItemDataBound()イベントの処理
このイベントは、DataGridのDataBind()メソッドが実行されたときに発生します。このイベントでは、DataGridのアイテム(DataGridItem)にクライアント側で動作するonClickイベントを登録します。これにより、DataGridの任意のセルをクリックして行を選択できるようになります
|
56: Sub
dgrdEmployees_ItemDataBound(s As Object, e As DataGridItemEventArgs) |
Sub dgrdEmployees_ItemCommand()イベントの処理
このイベントは、DataGridからアイテム(DataGridItem)を選択したときに発生します。このイベントでは、選択したアイテムの社員IDを取得してVie
|
68: Sub
dgrdEmployees_ItemCommand(s As Object, e As DataGridCommandEventArgs) |
Sub ibtnUpdate_Command()イベントの処理
このイベントは、レコード編集ボタンをクリックしたときに発生します。このイベントでは、InsertScripBlock()を呼び出して子ウィンドウを開きます。InsertScriptBlockの引数には、編集するレコードの社員IDを指定します。
|
75: Sub ibtnUpdate_Command(s
As Object, e As CommandEventArgs) |
Sub btnRefresh_Click()イベントの処理
このイベントは、子ウィンドウから親ウィンドウのTextBoxを書き換えたときに発生します。このTextBoxには、クライアント側で動作するonPropertyChangeイベントが登録されています。子ウィンドウからこのTextBoxを書き換えると、onPropertyChangeイベントが発生して親ウィンドウをポストバックします。親ウィンドウがポストバックされると、btnRefresh_Clickが実行されます。btnRedresh_Clickイベントでは、Session変数からカレントの社員IDを取得してDataGridの対応するアイテムを選択した状態にします。
ところで、btnRefresh_Clickイベントの前にPage_Loadイベントが発生していることに注意してください。つまり、Page_Loadイベントの初期化処理がすでに実行された状態でこのイベントに制御が渡ります。
行24-28のWith…End Withでは、DataGridにDataTableをバインドしてリフレッシュします。DataTableには、子ウィンドウで編集したレコードが反映されていますので、DataGridには最新のデータが表示されます。
行31-38では、Session変数に社員IDが保存されているか確認しています。社員IDが保存されていないときは、DataGridのアイテムを選択しないで戻ります。
行42-46のFor…Nextでは、DataTableのRo
行48-49では、Vie
|
23: Sub btnRefresh_Click(s As
Object, e As EventArgs) |
Sub InsertScriptBlock()の処理
このサブプロシージャでは、子ウィンドウを開くJavaScriptを生成して登録します。InsertScriptBlockは、編集ボタンをクリックしたときに、ボタンのOnCommandイベントから呼ばれます。
行99-101では、JavaScriptのwindow.open()メソッドの引数に指定するオプションを生成しています。行103-107のWith…End Withでは、StringBuilderのAppend()メソッドで以下のJavaScriptを生成しています。
<script
language='javascript'>
window.open('PopupEmployee.aspx?id=999','_blank','features');
</script>
JavaScriptのwindow.open()メソッドは、新規ウィンドウを開きます。Open()メソッドの引数には、url、target、featuresを指定します。urlには、新規ウィンドウに表示するファイルPopupEmployee.aspxを指定します。なお、このurlには、QueryStringに編集するレコードの社員IDを指定しています。
PopupEmployee.aspx?id=999
行108では、Page.RegisterClientScriptBlock()メソッドでJavaScriptを登録します。ここで登録したJavaScriptは、Webページがロードされたときにクライアント側のブラウザから実行されます。
|
98: Sub
InsertScriptBlock(intEmployeeID As Integer)
|
Sub BindDataGrid()の処理
このサブプロシージャでは、DataGridに社員テーブルをバインドして表示します。BindDataGridは、Page_Loadイベントから呼ばれます
行80では、社員テーブルからレコードを抽出するSQLを生成しています。SELECTステートメントには、Top 10のオプションを指定していますので、社員テーブルから10件のレコードが抽出されます。行81では、CreateDataSet()関数を呼び出して、社員テーブルのDataSetを作成しています。
行83では、DataSetのTablesコレクションから社員テーブルのDataTableを作成しています。行84では、DataTableのPrimaryKeyプロパティに社員テーブルの主キー(社員ID)のカラム名を設定しています。主キーを設定することにより、DataTableのRo
行86-93のWith…End Withでは、DataSetにDataTableをバインドしています。行94では、DataTableのRo
|
79: Sub BindDataGrid() 93: End With |
Function CreateDataSet()関数の処理
この関数は、データベースからレコードを抽出してDataSetを作成して返します。CreateDataSetは、BindDataGrid()から呼ばれます。CreateDataSetの引数には、strSQLとstrConnectionStringを指定します。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, _ |
リスト DataGridEmployee.aspxのソースコード(コード編)
|
1: <%@ Page language="vb"
SmartNavigation="false" %> |
◆サブプログラムPopupEmployee.aspxの解説(HTML編)
PopupEmployee.aspxのHTML編を解説します。このサブプログラムでは、親ウィンドウのDataGridから選択したレコードをWebページに表示して編集することができます。
行236-245のLabelとTextBoxでは、社員テーブルの社員IDを表示しています。TextBoxのReadOnlyプロパティには、Trueを設定して読み込み専用にしています。
行251-258のLabel、TextBoxでは、氏名を表示しています。このTextBoxには、RequiredFieldValidatorを定義してエラーチェックしています。後続するLabel、TextBoxでは、支社、入社日、備考を表示しています。支社、入社日、備考のTextBoxの右側にはImageButtonを定義していますが、このサンプルでは使用不可にしています。これらの使用不可のImageButtonには、CSSのfilterプロパティに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-360のLabelとDropDownListでは、エディタの種類を定義していますが、このサンプルでは使用不可にしています。
![]()
図 ImageButtonでレコード移動ボタンを表示した例
行363-370では、「更新」と「閉じる」のButtonを定義しています。更新ボタンには、OnClickイベントが登録されています。OnClickイベントでは、Webページから編集したレコードをDataTableに反映します。閉じるボタンには、OnClickイベントが登録されていませんが、ランタイム時にクライアント側で動作するonClickイベントを登録します。クライアント側で動作するonClickイベントでは、子ウィンドウを閉じます。
![]()
図 「更新」と「閉じる」ボタンを表示した例
リスト PopupEmployee.aspxのソースコード(HTML編)
|
219: <html> 251: <asp:Label id="lblName" runat="server" 335: <asp:ImageButton id="ibtnPrev" runat="server" 363: <asp:Button id="btnUpdate" runat="server" |
◆サブプログラムPopupEmployee.aspxの解説(コード編)
PopupEmployee.aspxでは、レコード移動ボタンをクリックしたときWebページに表示するレコードを移動します。
Sub Page_Load()イベントの処理
このイベントは、PopupEmployee.aspxがロードされたときに実行されます。このイベントでは、Webページに親ウィンドウから選択したレコードを表示します。
行9では、Session変数に保存されている社員テーブルのDataTableを取得しています。行18-22のIf…End Ifでは、ページが最初にロードされたか調べています。ページが最初にロードされたときは、閉じるボタンにクライアント側で動作するonClickイベントを登録しています。このonClickイベントでは、JavaScriptのwindow.close()メソッドで子ウィンドウを閉じます。次に、GetRecord()を呼び出して親ウィンドウのDataGridから選択したレコードをTextBoxに表示します。
|
8: Sub Page_Load() |
Sub ibtnPrev_Click()イベントの処理
このイベントは、Webページから左矢印のレコード移動ボタンをクリックしたときに発生します。このイベントは、現在表示されている1つ前のレコードを表示します。
行59では、TextBoxのTextプロパティから社員IDを取得しています。行60-61では、DataTableのSelect()メソッドでフィルタ条件に一致するレコードを抽出しています。Select()メソッドの引数には、フィルタ条件と並べ替えするカラムを指定します。Select()メソッドの戻り値としてDataRowが配列として返されます。
Dim arrRo
行64-78のIf…Else…End Ifでは、Select()メソッドから返されたレコード件数を調べています。レコードが1件以上返されたときは、カレント-1のレコードを表示します。レコードが1件のときは、カレントのレコードを再度表示します。
行65では、カレント-1のレコードを配列から取り出してDataRowを作成しています。行66では、DisplayRecord()を呼び出してDataRowをTextBoxに表示します。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) |
Sub ibtnNext_Click()イベントの処理
このイベントは、Webページから右矢印のレコード移動ボタンをクリックしたときに発生します。このイベントは、現在表示されている次のレコードを表示します。
行84では、TextBoxのTextプロパティから社員IDを取得しています。行85-86では、DataTableのSelect()メソッドでフィルタ条件に一致するレコードを抽出しています。Select()メソッドの戻り値としてDataRowが配列として返されます。
Dim arrRo
行89-103のIf…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) |
Sub PostBackMain()の処理
このサブプロシージャでは、親ウィンドウをポストバックするJavaScriptを生成して登録します。PostBackMainは、ibtnPrev_Click()とibtnNext_Click()イベントから呼ばれます。
行134-139のWith…End Withでは、StringBuilderのAppend()メソッドで以下のJavaScriptを生成しています。
<script
language='javascript'>
window.opener.frmMain.txtMessage.value = 'message';
</script>
JavaScriptのwindow.opener.frmMain.txtMessage.value =では、親ウィンドウのTextBoxに「message」を設定して書き換えています。このTextBoxには、クライアント側で動作するonPropertyChange()イベントが登録されています。TextBoxを書き換えると、このイベントが実行されて親ウィンドウがポストバックされます。親ウィンドウがポストバックされると、Webサーバ側でbtnRefresh_Click()イベントが実行されます。
行140では、Page.RegisterClientScriptBlock()メソッドでJavaScriptを登録しています。ここで登録したJavaScriptは、Webページがロードされたときにクライアントのブラウザから実行されます。
|
132: Sub PostBackMain(strMessage As String) |
Sub GetRecord()の処理
このサブプロシージャでは、親ウィンドウのDataGridから選択したレコードをTextBoxに表示します。GetRecord()は、Page_Loadイベントから呼ばれます。
行144では、QueryStringから社員IDを取得しています。
PopupEmployee.aspx?id=999
Request.QueryString("id")
è 999
行145では、DataTableのRo
行147では、DisplayRecord()を呼び出して検索したレコードをTextBoxに表示します。DisplayRecord()の引数には、DataRowを指定します。
行148では、SetButtons()を呼び出して移動ボタンを使用可、または使用不可にしています。カレントレコードが、先頭レコードのときは左矢印ボタンが使用不可になり、最終レコードのときは右矢印ボタンが使用不可になります。
|
143: Sub GetRecord() |
Sub DisplayRecord()の処理
このサブプロシージャでは、レコードの内容をTextBoxに表示します。DisplayRecordは、ibtnPrev_Click()、ibtnNext_Click()、GetRecord()から呼ばれます。
行152-165のIf…Else…End Ifでは、DataRowにレコードが格納されているか調べています。レコードが格納されているときは、DataRowからカラム値を取得してTextBoxに設定します。レコードが格納されていないときは、TextBoxに空白を設定します。
|
151: Sub DisplayRecord(dr As DataRow) |
Sub SetButtons()の処理
このサブプロシージャでは、レコード移動ボタンを使用可、または使用不可の状態に切り替えます。SetButtonsは、GetRecord()から呼ばれます。
行169-179のIf…Else…End Ifでは、DataTableのレコード件数を調べています。レコード件数が1のときは、双方のレコード移動ボタンを使用不可の状態にします。レコード件数が1以外のときは、双方のボタンを使用可能状態にします。
|
168: Sub SetButtons() |
リスト PopupEmployee.aspxのソースコード(コード編)
|
1: <%@ Page language="vb"
SmartNavigation="False" > |