DataGridにレコードの追加、修正、削除機能を付加するには

 

  DataGridにレコードの追加、修正、削除機能を付加するサンプル(手動方式)

 

DataGridにレコードの追加、修正、削除機能を付加するサンプル(手動方式)

 

このサンプルでは、DataGridにレコードの追加、修正、削除機能を追加しています。DataGridには、編集ボタン、削除ボタン、新規登録ボタンが表示されます。編集ボタンをクリックすると編集モードに切り替わって、確定、中止ボタンが表示されますので、レコードを編集して確定ボタンをクリックします。編集をキャンセルするときは、中止ボタンをクリックします。削除ボタンをクリックすると、ポップアップウィンドウに確認の問い合わせメッセージが表示されますので、OKボタンをクリックします。新規登録ボタンをクリックすると、空白行が挿入されて編集モードに切り替わりますのでデータを入力して確定ボタンをクリックします。新規登録ボタンは、最終ページに移動したとき使用可能になります。

 

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

 

  DataGridにレコードの追加機能を付加する方法

  DataGridにレコードの削除機能を付加する方法

  DataGridに削除ボタンを表示する方法

  DataGridのフッタに新規登録ボタンを表示する方法

  DataGridのセルを結合する方法

  削除ボタンに問い合わせのメッセージを表示する方法

  編集ボタンをクリックしたときにTextBoxにフォーカスを移動する方法

 

サンプルの行204-284では、DataGridを定義しています。行211-213では、DataGridOnEditCommand, OnUpdateCommand, OnCancelCommandイベントを登録しています。これらのイベントでは、レコードの編集に関連する処理を行います。行215では、OnDeleteCommandイベントを登録しています。このイベントでは、レコードの削除処理を行います。行226-283<Columns>…</Columns>では、BoundColumn, TemplateColumn, EditCommandColumnで得意先ID、得意先名、担当者名、電話番号、編集ボタン、削除ボタン、新規登録ボタンを表示しています。

 

204: <asp:DataGrid id="dgrdCustomers" runat="server"
211:   OnEditCommand="dgrdCustomers_EditCommand"
212:   OnUpdateCommand="dgrdCustomers_UpdateCommand"
213:   OnCancelCommand="dgrdCustomers_CancelCommand"
215:   OnDeleteCommand="dgrdCustomers_DeleteCommand"
        ::: >
226:   <Columns>

::::
283:   </Columns>
284: </asp:DataGrid>

 

227-231では、BoundColumnで得意先IDを表示しています。ReadOnlyプロパティにTrueを設定して読み込み専用にしています。この場合、編集ボタンをクリックしても編集することができません。

 

227:     <asp:BoundColumn
228:       DataField="CustomerID"
229:       HeaderText="ID"
230:       ReadOnly="True"
231:       ItemStyle-HorizontalAlign="Right" />

 

232-241では、TemplateColumnで得意先名を表示しています。得意先名は、BoundColumnを使用して表示することもできますが、編集ボタンをクリックしたときに自動的にフォーカスを移動するためにTemplateColumnを使用しています。ItemTemplateでは、LabelTextプロパティに得意先名をバインドしています。EditItemTemplateでは、TextBoxTextプロパティに得意先名をバインドしています。EditItemTemplateは、編集モードのときに表示されます。ItemTemplateは、通常モードのときに表示されます。

 

232:     <asp:TemplateColumn HeaderText="得意先名">
233:       <ItemTemplate>
234:         <asp:Label id="lblCustomerName" runat="server"
235:           Text='<%# Container.DataItem("CompanyName") %>' />
236:       </ItemTemplate>
237:       <EditItemTemplate>
238:         <asp:TextBox id="txtCustomerName" runat="server"
239:           Text='<%# Container.DataItem("CompanyName") %>' />
240:       </EditItemTemplate>
241:     </asp:TemplateColumn>

 

242-243では、BoundColumnで担当者名を表示しています。

 

242:     <asp:BoundColumn
243:       DataField="ContactName" HeaderText="
担当者名" />

 

244-261では、TemplateColumnで電話番号を表示しています。電話番号は、BoundColumnでも表示できますが、フッタに新規登録ボタンを表示するためにTemplateColumnを使用しています。ItemTemplateでは、LabelTextプロパティに電話番号をバインドしています。EditItemTemplateでは、TextBoxTextプロパティに電話番号をバインドしています。FooterTemplateでは、Buttonで新規登録ボタンを表示しています。行256では、ButtonOnClickイベントを登録しています。OnClickイベントでは、DataGridに空白行を挿入して編集モードに切り替えます。行257では、EnabledプロパティにIsLastPage()関数をバインドしています。IsLastPage()関数は、最終ページのときTrueを返します。最終ページ以外のときは、Falseを返します。新規登録ボタンは、最終ページが表示されたときのみ使用可能になります。

 

244:     <asp:TemplateColumn HeaderText="電話番号">
245:       <ItemTemplate>
246:         <asp:Label id="lblPhone" runat="server"
247:           Text='<%# Container.DataItem("Phone") %>' />
248:       </ItemTemplate>
249:       <EditItemTemplate>
250:         <asp:TextBox id="txtPhone" runat="server"
251:           Text='<%# Container.DataItem("Phone") %>' />
252:       </EditItemTemplate>
253:       <FooterTemplate>
254:         <asp:Button id="btnAddRow" runat="server"
256:           OnClick="btnAddRow_Click"
257:           Enabled='<%# IsLastPage() %>'
259:           Text="
新規登録" />
260:       </FooterTemplate>
261:     </asp:TemplateColumn>

 

262-269では、EditCommandColumnで編集ボタン、確定ボタン、中止ボタンを定義しています。確定ボタンと中止ボタンは、編集モードのときに表示されます。

 

262:     <asp:EditCommandColumn
263:       ButtonType="PushButton"
264:       EditText="
編集"
265:       UpdateText="
確定"
266:       CancelText="
中止">
269:     </asp:EditCommandColumn>

 

270-282では、TemplateColumnで削除ボタンを表示しています。HeaderTemplateでは、LabelTextプロパティに「ボタン」を設定してヘッダに表示しています。ここで設定した見出しは、DataGridOnItemDataBoundイベントで、編集ボタンのセルと結合して表示します。ItemTemplateでは、Buttonで削除ボタンを表示しています。ButtonCommandNameプロパティにDeleteを設定すると、削除ボタンをクリックしたときにDataGridOnDeleteCommandイベントが発生します。OnDeleteCommandイベントでは、レコードの削除処理を行います。

 

270:     <asp:TemplateColumn>
271:       <HeaderTemplate>
272:         <asp:Label id="lblButton" runat="server"
273:           Text="
ボタン" />
274:       </HeaderTemplate>
275:       <ItemTemplate>
276:         <asp:Button id="btnDelete" runat="server"
277:           CommandName="Delete"
278:           Text="
削除" />
279:       </ItemTemplate>
282:     </asp:TemplateColumn>

 

Sub Page_Load()イベントでは、得意先テーブルのレコードを抽出してDataGridにバインドします。行10では、Cacheのキーを生成しています。行12-13は、ページが最初にロードされたときに実行されます。Sub LoadData()では、得意先テーブルからレコードを抽出してDataTableを生成します。DataTableは、ポストバックされたときに再使用するためにメモリ上にキャッシュします。このサンプルでは、CacheInsert()メソッドでDataTableをキャッシュしています。

 

Cache.Insert(mstrCacheKey, mdt, Nothing, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5))

 

CacheInsert()メソッドには、5分以上キャッシュが参照されないとき自動的に無効になるようにTimeSpan.FromMinutes(5)を指定しています。行15-18は、ページがポストバックされたときに実行されます。行15では、メモリ上にキャッシュされているDataTableを変数に保存しています。行16-18If…End Ifでは、キャッシュが無効になっているか調べています。無効になっているときは、Sub LoadData()を呼び出してDataTableを生成します。

 

  9: Sub Page_Load()
 10:   mstrCacheKey = "Customers" & Request.Path
 11:   If Not IsPostBack Then
 12:     LoadData()
 13:     BindDataGrid()
 14:   Else
 15:     mdt = Cache(mstrCacheKey)
 16:     If mdt Is Nothing Then
 17:       LoadData()
 18:     End If
 19:   End If
 20: End Sub

 

Sub btnAddRow_Click()では、DataGridに空白行を挿入して編集モードに切り替えています。このイベントは、新規登録ボタンをクリックすると発生します。行45-46では、DataTableNewRow()メソッドでDataRowを生成して、Add()メソッドでDataTableに追加しています。DataRowのカラムには何も設定していないので空白のレコードが追加されます。行47-48では、CacheInsert()メソッドでDataTableをメモリ上にキャッシュしています。行49-54では、ページ番号と編集行を調整しています。新規登録したレコードが次ページに表示されるときは、CurrentPageIndexプロパティを+1加算して、EditItemIndexプロパティに0を設定します。新規登録したレコードが最終ページに収まるときは、調整不要です。行55では、Sub BindDataGrid()を呼び出してDataTableをバインドしています。これで新規登録したレコードがDataGridに編集モードの状態で表示されます。

 

44: Sub btnAddRow_Click(s As Object, e As EventArgs)
 45:   Dim dr As DataRow = mdt.NewRow()
 46:   mdt.Rows.Add(dr)
 47:   Cache.Insert(mstrCacheKey, mdt, Nothing, _
 48:     Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5))

49:   Dim intNewItemIndex As Integer = dgrdCustomers.Items.Count
 50:   If intNewItemIndex >= dgrdCustomers.PageSize Then
 51:      dgrdCustomers.CurrentPageIndex += 1
 52:      intNewItemIndex = 0
 53:   End If
 54:   dgrdCustomers.EditItemIndex = intNewItemIndex
 55:   BindDataGrid()
 60: End Sub

 

新規登録した空白レコードが表示されたら、データを入力して確定ボタンをクリックするとOnUpdateCommandイベントが発生します。OnUpdateCommandイベントでは、DataGridで編集したレコードをSQLInsert/Updateステートメントを使用してデータベースに書き込みます。行76-78では、SQLInsertステートメントを生成しています。行79-80では、SQLUpdateステートメントを生成しています。OleDbCommandBuilderクラスを使用するとInsert/UpdateSQLを自動生成することができますが、このサンプルでは手動で生成しています。行81-82では、OleDbConnectionのインスタンスを生成しています。引数には、Web.configに登録されているデータベース接続情報を指定しています。

 

86-88では、DataGridの編集行から得意先名、担当者名、電話番号を取得して変数に保存しています。得意先名、電話番号のようにTemplateColumnEditItemTemplateで定義されているときは、DataGridCommandEventArgsItem.FindControl()メソッドでTextBoxを検索してTextプロパティから値を取得します。担当者名のようにBoundColumnで定義されているときは、TextBoxが自動生成されますので、Item.Cells().Controls()プロパティを参照してTextBoxTextプロパティから値を取得します。

 

90-108では、SQLInsert/Updateステートメントのパラメータに値を設定しています。行90では、DataTableRows()コレクションから最終レコードのDataRowを生成しています。DataRowRowStateプロパティを調べて新規登録されたときは、Insert用のOleDbCommandを生成してパラメータに値を設定します。レコードの更新のときは、Update用のOleDbCommandを生成してパラメータに値を設定します。

 

110-112では、編集したレコードをデータベースに書き込んでいます。行110では、OleDbConnectionOpen()メソッドでデータベースを開いています。行111では、OleDbCommandExecuteNonQuery()メソッドでInsert/Updateステートメントを実行しています。行112では、OleDbConnectionClose()メソッドでデータベースを閉じています。

 

113-115では、編集モードを解除して得意先テーブルからレコードを抽出してDataGridにバインドしています。DataGridEditItemIndexプロパティに-1を設定すると編集モードが解除されます。Sub LoadData()では、得意先テーブルからレコードを抽出してDataTableを生成します。Sub BindDataGrid()では、DataGridDataTableをバインドして表示します。これで新規登録/編集したレコードがDataGridに再表示されます。

 

75: Sub dgrdCustomers_UpdateCommand(s As Object, e As DataGridCommandEventArgs)
 76:   Dim strSqlInsert As String = "Insert Into Customers " & _
 77:     "(CompanyName, ContactName, Phone) " & _
 78:     "Values(@CustomerName, @ContactName, @Phone)"
 79:   Dim strSqlUpdate As String = "Update Customers Set CompanyName=@CustomerName," & _
 80:     "ContactName=@ContactName, Phone=@Phone Where CustomerID=@CustomerID"
 81:   Dim con As New OleDbConnection( _
 82:     ConfigurationSettings.AppSettings("conStringNw"))
 83:   Dim cmd As OleDbCommand
 85:   Dim intCustomerID As Integer
 86:   Dim strCustomerName As String = CType(e.Item.FindControl("txtCustomerName"), TextBox).Text
 87:   Dim strContactName As String = CType(e.Item.Cells(2).Controls(0), TextBox).Text
 88:   Dim strPhone As String = CType(e.Item.FindControl("txtPhone"), TextBox).Text
 90:   Dim drLast As DataRow = mdt.Rows((mdt.Rows.Count - 1))
 91:   If drLast.RowState = DataRowState.Added Then
 93:     cmd = New OleDbCommand(strSqlInsert, con)
 94:     With cmd.Parameters
 95:       .Add("@CustomerName",strCustomerName)
 96:       .Add("@ContactName",strContactName)
 97:       .Add("@Phone",strPhone)
 98:     End With
 99:   Else
100:     cmd = New OleDbCommand(strSqlUpdate, con)
101:     intCustomerID = dgrdCustomers.DataKeys(e.Item.ItemIndex)
102:     With cmd.Parameters
103:       .Add("@CustomerName",strCustomerName)
104:       .Add("@ContactName",strContactName)
105:       .Add("@Phone",strPhone)
106:       .Add("@CustomerID",intCustomerID)
107:     End With
108:   End If
110:   con.Open()
111:   cmd.ExecuteNonQuery()
112:   con.Close()
113:   dgrdCustomers.EditItemIndex = -1
114:   LoadData()
115:   BindDataGrid()
116: End Sub

 

DataGridから編集ボタンをクリックすると、OnEditCommandイベントが発生します。OnEditCommandイベントでは、該当行を編集モードで再表示します。行68では、DataGridEditItemIndexプロパティに編集行のインデックス番号を設定しています。行69では、Sub BindDataGrid()を呼び出して、DataGridDataTableをバインドしています。これで、EditItemIndexに設定した行が編集モードで表示されます。

 

70-72では、DataGridに編集行が表示されるときにフォーカスを得意先名に移動するための処理を行っています。行70-71では、DataGridから得意先名のTextBoxのコントロールを取得しています。得意先名のTextBoxは、TemplateColumnで定義されていますので、FindControl()メソッドを使用して検索します。Sub SetFocus()では、フォーカスを移動するためのJavaScriptを生成して登録しています。

 

67: Sub dgrdCustomers_EditCommand(s As Object, e As DataGridCommandEventArgs)
 68:   dgrdCustomers.EditItemIndex = e.Item.ItemIndex
 69:   BindDataGrid()
 70:   Dim ctrlToFocus As TextBox = _
 71:     dgrdCustomers.Items(e.Item.ItemIndex).Cells(1).FindControl("txtCustomerName")
 72:   SetFocus(ctrlToFocus)
 73: End Sub

 

Sub SetFocus()では、StringBuilderAppend()メソッドで以下のようなJavaScriptを生成してRegisterStartupScript()メソッドで登録しています。

 

<script language='JavaScript'>

frmAddNew.dgrdCustomers__ctl3_txtCustomerName.focus();

frmAddNew.dgrdCustomers__ctl3_txtCustomerName.select();

</script>

 

RegisterStartupScript()メソッドで登録したJavsScriptは、HTMLページの最後に追加されて実行されます。JavaScriptが実行されると、フォーカスが得意先名のTextBoxに移動してデータが選択された状態で表示されます。

 

frmAddNewのエレメント名(dgrdCustomers_ctl3_txtCustomerName)は、TextBoxClientIDプロパティから取得した値です。

 

<input name="dgrdCustomers:_ctl3:txtCustomerName" type="text" value="フレンドリーソフト"

id="dgrdCustomers__ctl3_txtCustomerName" />

 

DataGridで生成される<input type=”text”…>タグのid=は、ユニークになるようにシーケンス番号が付加されます。ClientIDプロパティを使用すると、DataGridが生成したidを取得することができます。

 

177: Sub SetFocus(ctrlToFocus As TextBox)
178:   If Not (ctrlToFocus Is Nothing) Then
179:     Dim sbScript As New StringBuilder("")
180:     With sbScript
181:       .Append("<script language='JavaScript'>" & vbCrLf)
182:       .Append(vbTab & "frmAddNew." & ctrlToFocus.ClientID & ".focus();" & vbCrLf)
183:       .Append(vbTab & "frmAddNew." & ctrlToFocus.ClientID & ".select();" & vbCrLf)
184:       .Append("<" & "/script>")
185:     End With
186:     RegisterStartupScript("focus", sbScript.ToString)
187:   End If
188: End Sub

 

レコードが編集モードで表示されているとき、中止ボタンをクリックするとOnCancelCommandイベントが発生します。このイベントでは、新規登録/編集をキャンセルしてDataGridを再表示します。行119では、DataGridEditItemIndexプロパティに-1を設定して編集モードを解除しています。行120では、DataTableの最終レコードのDataRowを生成しています。行121-128If…End Ifでは、最終レコードが新規登録されたか調べています。新規登録されたときは、DataRowRejectChanges()メソッドで新規登録前の状態に戻します。行123-125では、カレントページを調整しています。行126-127では、CacheInsert()メソッドでDataTableを上書きして最新にしています。行129では、Sub BindDataGrid()を呼び出して、DataGridDataTableをバインドして再表示しています。

 

118: Sub dgrdCustomers_CancelCommand(s As Object, e As DataGridCommandEventArgs)
119:   dgrdCustomers.EditItemIndex = -1
120:   Dim drLast As DataRow = mdt.Rows((mdt.Rows.Count - 1))
121:   If drLast.RowState = DataRowState.Added Then
122:     drLast.RejectChanges()
123:     If dgrdCustomers.Items.Count = 1 Then
124:       dgrdCustomers.CurrentPageIndex -= 1
125:     End If
126:     Cache.Insert(mstrCacheKey, mdt, Nothing, _
127:       Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5))
128:   End If
129:   BindDataGrid()
130: End Sub

 

DataGridから削除ボタンをクリックすると、OnDeleteCommandイベントが発生します。このイベントでは、得意先テーブルからレコードを削除してDataGridを再表示します。行133-134では、SQLDeleteステートメントを生成しています。行135-137では、OleDbConnection, OldDbCommandのインスタンスを生成しています。行138-140では、DataGridDataKeys()プロパティから得意先IDの値を取得してDeleteステートメントのパラメータに設定しています。行141-143では、SQLDeleteステートメントを実行して得意先テーブルからレコードを削除しています。行144-146では、カレントのページ番号を調整しています。行148-149では、得意先テーブルからレコードを抽出してDataTableを生成してDataGridにバインドしています。これで、DataGridにはレコードが削除された状態で表示されます。

 

132: Sub dgrdCustomers_DeleteCommand(s As Object, e As DataGridCommandEventArgs)
133:   Dim strSQL as String = "Delete From Customers " & _
134:     "Where CustomerID=@CustomerID"
135:   Dim con as New OleDbConnection( _
136:     ConfigurationSettings.AppSettings("conStringNw"))
137:   Dim cmd as New OleDbCommand(strSQL, con)
138:   Dim intCustomerID As Integer = dgrdCustomers.DataKeys(e.Item.ItemIndex)
140:   cmd.Parameters.Add("@CustomerID",intCustomerID)
141:   con.Open()
142:   cmd.ExecuteNonQuery()
143:   con.Close()
144:   If dgrdCustomers.Items.Count = 1 Then
145:     dgrdCustomers.CurrentPageIndex -= 1
146:   End If
148:   LoadData()
149:   BindDataGrid()
150: End Sub

 

DataGridから削除ボタンをクリックしたとき、問い合わせのメッセージが表示されますが、このメッセージはJavaScriptで表示しています。削除ボタンをクリックしたときにメッセージを表示するには、削除ボタンのOnClickイベントにJavaScriptを記述します。削除ボタンにOnClickイベントを登録するには、DataGridOnItemDataBoundイベントで行います。OnItemDataBoundイベントは、DataGridDataBind()メソッドを実行したときに発生します。OnItemDataBoundイベントの行161-163では、削除ボタンにOnClickイベントを登録しています。行161では、FindControl()メソッドで削除ボタンのコントロールを検索しています。削除ボタンは、TemplateColumnで定義されていますのでItem.Cells().Controls()は使用できません。行162-163では、ButtonAttributes.Add()メソッドでOnClickイベントとJavaScriptを登録しています。Add()メソッドを実行すると、以下のようなHTMLが生成されます。

 

<input type="submit" name="dgrdCustomers:_ctl3:btnDelete" value="削除"

  id="dgrdCustomers__ctl3_btnDelete"

  onClick="return confirm('得意先ID 121 を削除してよろしいですか?')" />

 

OnItemDataBoundイベントでは、さらにDataGridのヘッダのセルを結合して表示しています。行155-158では、編集ボタンと削除ボタンのセルを結合してヘッダ「ボタン」をセンタリングして表示しています。フッタに表示する新規登録のボタンもセルを結合してセンタリングして表示しています。

 

152: Sub dgrdCustomers_ItemDataBound(s As Object, e As DataGridItemEventArgs)
153:   Dim lit As ListItemType = e.Item.ItemType
154:   If lit = ListItemType.Header Then
155:     Dim cellEditButton As TableCell = e.Item.Cells(4)
156:     e.Item.Cells.Remove(cellEditButton)
157:     cellEditButton = e.Item.Cells(4)
158:     cellEditButton.ColumnSpan = 2
160:   ElseIf lit = ListItemType.Item or lit = ListItemType.AlternatingItem Then
161:     Dim btnDelete As Button = CType(e.Item.FindControl("btnDelete"),Button)
162:     btnDelete.Attributes.Add("onClick", _
163:     "return confirm('
得意先ID " & DataBinder.Eval(e.Item.DataItem,"CustomerID") &

 " を削除してよろしいですか?')")
165:   ElseIf lit = ListItemType.Footer Then
         ::::
174:   End If
175: End Sub

 

  DataGridにレコードの追加、修正、削除機能を付加するサンプル(自動方式)

 

DataGridにレコードの追加、修正、削除機能を付加するサンプル(自動方式)

 

このサンプルは、DataGridにレコードの追加、修正、削除機能を追加しています。ユーザインタフェースは、手動方式と同じです。このサンプルでは、DataGridから追加、修正、削除したレコードをデータベースに反映させる処理をOleDbDataAdapterUpdate()メソッドで自動化しています。

 

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

 

  DataGridから追加、修正、削除したレコードをデータベースに反映する処理を自動化する方法

  OleDbCommandBuilderInsert, Update, DeleteSQLを自動生成する方法

  OleDbDataAdapterUpdate()メソッドの使い方

  DataTablePrimaryKeyを追加する方法

  DataColumnAutoincrement, AutoincrementSeed, AutoincrementStepプロパティの使い方

 

サンプルの行184-264では、DataGridを定義しています。行206-263<Columns>…</Columns>では、得意先テーブルの得意先ID、得意先名、担当者名、電話番号をバインドして表示しています。また、新規登録、編集、削除ボタンに各種イベントを登録して処理しています。

 

184: <asp:DataGrid id="dgrdCustomers" runat="server"
191:   OnEditCommand="dgrdCustomers_EditCommand"
192:   OnUpdateCommand="dgrdCustomers_UpdateCommand"
193:   OnCancelCommand="dgrdCustomers_CancelCommand"
194:   OnItemDataBound="dgrdCustomers_ItemDataBound"
195:   OnDeleteCommand="dgrdCustomers_DeleteCommand"
        :::: >

206:   <Columns>

::::
263:   </Columns>
264: </asp:DataGrid>

 

Page_Load()イベントでは、得意先テーブルからレコードを抽出してDataGridにバインドしています。行13では、SQLSelectステートメントを生成しています。行14-15では、OleDbConnectionOleDbDataAdapterのインスタンスを生成しています。行16では、OleDbCommandBuilderInsert, Update, DeleteSQLを生成しています。これらのSQLは、行13Selectステートメントをベースに生成します。行19-20は、ページが最初にロードされたときに実行されます。Sub LoadData()では、得意先テーブルからレコードを抽出してDataTableを生成します。Sub BindDataGrid()では、DataGridDataTableをバインドして表示します。行22-25は、ページがポストバックされたときに実行されます。メモリ上にキャッシュされているDataTableを変数に保存してキャッシュが無効になっているか調べます。無効になっているときは、Sub LoadData()を呼び出してDataTableを生成します。

 

12: Sub Page_Load()
 13:   Dim strSQL As String = "Select * From Customers Order by CustomerID"
 14:   mcon = New OleDbConnection(ConfigurationSettings.AppSettings("conStringNw"))
 15:   mda = New OleDbDataAdapter(strSQL, mcon)
 16:   mcb = New OleDbCommandBuilder(mda)

17:   mstrCacheKey = "Customers" & Request.Path
 18:   If Not IsPostBack Then
 19:     LoadData()
 20:     BindDataGrid()
 21:   Else
 22:     mdt = Cache(mstrCacheKey)
 23:     If mdt Is Nothing Then
 24:       LoadData()
 25:     End If
 26:   End If
 27: End Sub

 

Sub LoadData()の行31では、OleDbDataAdapterFill()メソッドで得意先テーブルからレコードを抽出してDataSetに格納します。行32では、DataSetTablesコレクションから得意先テーブルのDataTableを生成して変数に保存します。行33では、得意先IDDataColumnを生成しています。行34では、DataColumnAutoincrementプロパティにTrueを設定してオートナンバー型にしています。行35-36では、開始値と増減値を設定しています。DataTableに新規レコードを追加すると得意先IDは自動採番されますが、ここで採番されたIDは、DataTableの最終レコードのID+1加算した仮IDです。実際のIDは、得意先テーブルに反映したときに確定します。このサンプルでは、仮IDと本IDを区別するために仮IDを負の数で表示するようにしています。行37では、得意先ID(CustomerID)を主キーに設定しています。行38-39では、DataTableをメモリ上にキャッシュしています。

 

29: Sub LoadData()
 30:   Dim ds = New DataSet()
 31:   mda.Fill(ds,"Customers")
 32:   mdt = ds.Tables("Customers")
 33:   Dim dc As DataColumn = mdt.Columns("CustomerID")
 34:   dc.Autoincrement = True
 35:   dc.AutoincrementSeed = -1
 36:   dc.AutoincrementStep = -1
 37:   mdt.PrimaryKey = New DataColumn() {mdt.Columns("CustomerID")}
 38:   Cache.Insert(mstrCacheKey, mdt, Nothing, _
 39:     Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5))
 40: End Sub

 

DataGridが編集モードで表示されているとき、レコードを編集して確定(更新)ボタンをクリックするとOnUpdateCommadイベントが発生します。このイベントでは、OleDbDataAdapterUpdate()メソッドを使用して編集されたレコードをデータベースに反映しています。行82では、DataGridDataKeys()プロパティから主キー(CustomerID)の値を取得しています。行83-85では、DataGridの編集行から得意先名、担当者名、電話番号の値を取得しています。行87では、DataTableRowsコレクションから最終レコードのDataRowを生成しています。行88-90では、DataRowRowStateプロパティを参照して最終レコードが新規登録されたレコードか調べています。

 

既存レコードの更新のときは、DataTableRowsコレクションのFind()メソッドでレコードを検索します。Find()メソッドでレコードが見つかったときは、DataRowが返されます。見つからないときは、Nullが返されます。行91-95では、Find()メソッドでレコードが見つかったかどうか調べて、DataRowの得意先名、担当者名、電話番号を更新しています。行96では、OleDbDataAdapterUpdate()メソッドでDataTableをデータベースに書き込んでいます。Update()メソッドでは、OleDbCommandBuilderで生成したSQLコマンド(Insert, Update, Delete)を使用します。行98では、DataGridEditItemIndexプロパティに-1を設定して編集モードを解除しています。行99-100では、得意先テーブルからレコードを抽出してDataTableを生成してDataGridにバインドしています。これで、得意先テーブルから抽出されたレコードがDataGridに表示されます。DataGridから新規登録ボタンをクリックして編集モードのときは、得意先IDが仮ID(負の数)として表示されますが、確定ボタンをクリックした後は本ID(正の数)として表示されます。

 

81: Sub dgrdCustomers_UpdateCommand(s As Object, e As DataGridCommandEventArgs)
 82:   Dim intCustomerID As Integer = dgrdCustomers.DataKeys(e.Item.ItemIndex)
 83:   Dim strCustomerName As String = CType(e.Item.FindControl("txtCustomerName"), TextBox).Text
 84:   Dim strContactName As String = CType(e.Item.Cells(2).Controls(0), TextBox).Text
 85:   Dim strPhone As String = CType(e.Item.FindControl("txtPhone"), TextBox).Text
 87:   Dim dr As DataRow = mdt.Rows((mdt.Rows.Count - 1))
 88:   If dr.RowState <> DataRowState.Added Then
 89:     dr = mdt.Rows.Find(intCustomerID)
 90:   End If
 91:   If Not (dr Is Nothing) Then
 92:     dr("CompanyName") = strCustomerName
 93:     dr("ContactName") = strContactName
 94:     dr("Phone") = strPhone
 95:   End If
 96:   mda.Update(mdt)
 98:   dgrdCustomers.EditItemIndex = -1
 99:   LoadData()
100:   BindDataGrid()
101: End Sub

 

DataGridから削除ボタンをクリックしたときは、OnDeleteCommandイベントが発生します。このイベントでは、DataTableRowsコレクションのFind()メソッドで削除レコードを検索して、DataRowDeleteメソッドで削除します。DataTableから削除されたレコードは、OleDbDataAdapterUpdate()メソッドでデータベースに反映しています。Update()メソッドは、OleDbCommandBuilderが生成したSQLDeleteステートメントを使用して得意先テーブルからレコードを削除します。

 

117: Sub dgrdCustomers_DeleteCommand(s As Object, e As DataGridCommandEventArgs)
118:   Dim intCustomerID As Integer = dgrdCustomers.DataKeys(e.Item.ItemIndex)
119:   Dim dr As DataRow = mdt.Rows.Find(intCustomerID)
120:   If Not (dr Is Nothing) Then
121:     dr.delete
122:   End If
123:   mda.Update(mdt)
124:   If dgrdCustomers.Items.Count = 1 Then

125:     dgrdCustomers.CurrentPageIndex -= 1
126:   End If
127:   dgrdCustomers.EditItemIndex = -1
128:   LoadData()
129:   BindDataGrid()
130: End Sub

 

 

DataGridのフッタから新規レコードを追加するサンプル

 

ダウンロードにDataGridのフッタから新規レコードを追加するサンプルが収録されています。DataGridのフッタに新規レコードを入力するTextBoxが常時表示されていますので、データを入力したら追加ボタンをクリックして登録します。

 

DataGridのフッタから新規レコードを追加するサンプル

 

このサンプルでは、フッタのTextBoxにフォーカスを移動すると背景色が緑色で表示されます。TextBoxにカスタムカーソルを表示するには、TextBoxOnFocusOnBlurイベントを登録して背景色を書き換えます。OnFocusOnBlurイベントの登録は、DataGridOnItemDataBoundイベントで行います。行173-183では、得意先名、担当者名、電話番号のTextBoxOnFocusOnBlurイベントを登録しています。

 

OnItemDataBoundイベントでは、その他に削除ボタンにOnClickイベントを登録して問い合わせのメッセージを表示しています。問い合わせのメッセージには、得意先名が表示されます。OnItemDataBoundイベントで得意先名を取得するには、DataGridItemEventArgsItem.DataItemプロパティを使用します。

 

DataBinder.Eval(e.Item.DataItem,”CompanyName”)

 

160: Sub dgrdCustomers_ItemDataBound(s As Object, e As DataGridItemEventArgs)
161:   Dim lit As ListItemType = e.Item.ItemType
162:   Dim btn As Button
163:   Dim txt As TextBox
164:
165:   If lit = ListItemType.Header Then
166:
167:   ElseIf lit = ListItemType.Item or lit = ListItemType.AlternatingItem
168:     btn = e.Item.FindControl("btnDelete")
169:     btn.Attributes.Add("onClick", _
170:       "return confirm('
" & DataBinder.Eval(e.Item.DataItem,"CompanyName") & "

を削除してよろしいですか?')")
171:
172:   ElseIf lit = ListItemType.Footer Then
173:     txt = e.Item.FindControl("txtCustomerName2")
174:     txt.Attributes.Add("onFocus","this.style.backgroundColor='lightgreen'")
175:     txt.Attributes.Add("onBlur","this.style.backgroundColor='white'")
176:
177:     txt = e.Item.FindControl("txtContactName2")
178:     txt.Attributes.Add("onFocus","this.style.backgroundColor='lightgreen'")
179:     txt.Attributes.Add("onBlur","this.style.backgroundColor='white'")
180:
181:     txt = e.Item.FindControl("txtPhone2")

182:     txt.Attributes.Add("onFocus","this.style.backgroundColor='lightgreen'")
183:     txt.Attributes.Add("onBlur","this.style.backgroundColor='white'")
185:   End If
186: End Sub

 

 

ASP.NET DataGridのホームへ戻る