DataGridの編集時DropDownListから選択するには
● DataGridの編集時DropDownListから選択するサンプル

図 DataGridの編集時DropDownListから選択するサンプル
このサンプルは、DataGridから商品テーブルを編集するとき商品区分IDをDropDownListから選択して変更します。TextBoxに商品区分IDを直接入力する代わりに、DropDownListから選択するように設計すると使い勝手のよいWebアプリケーションを構築することができます。
このサンプルでは、以下のノウハウを習得することができます。
▲ DataGridのTemplateColumnの使い方
▲ EditItemTemplateにDropDownListを表示する方法
▲ DropDownListのデフォルト値をランタイム時に設定する方法
▲ ListItemコレクションのFindByValue(), FindByText(), IndexOf()メソッドの使い方
▲ DataSetに複数のDataTableを格納する方法
サンプルの行101-149では、DataGridを定義しています。行120-148の<Columns>…</Columns>では、BoundColumn、TemplateColumn、EditCommandColumnで商品テーブルの商品ID、商品名、商品区分名、編集ボタンを表示しています。
101: <asp:DataGrid
id="dgrdProducts" runat="server"
106:
OnItemDataBound="dgrdProducts_ItemDataBound"
108:
OnEditCommand="dgrdProducts_EditCommand"
109:
OnUpdateCommand="dgrdProducts_UpdateCommand"
110:
OnCancelCommand="dgrdProducts_CancelCommand"
::::
>
120: <Columns>
::::
148:
</Columns>
149: </asp:DataGrid>
行128-138のTemplateColumnでは、商品区分を表示しています。行129-131のItemTemplateでは、商品区分テーブルの商品区分名をバインドしています。行132-137のEditItemTemplateでは、DropDownListを表示しています。行134では、DropDownListのDataSourceプロパティにGetCategory()関数をバインドしています。GetCategory()は、DataSetから商品区分テーブルのDataTableを生成して返します。つまり、DataSourceに商品区分テーブルのDataTableを設定しています。行135-136では、DropDownListのDataValueField, DataTextFieldプロパティに商品区分ID、商品区分名のフィールドを設定しています。
128: <asp:TemplateColumn
HeaderText="商品区分">
129:
<ItemTemplate>
130:
<%#
Container.DataItem("CategoryName") %>
131:
</ItemTemplate>
132:
<EditItemTemplate>
133: <asp:DropDownList
id="dropCategories" runat="server"
134:
DataSource='<%# GetCategory() %>'
135:
DataValueField = "CategoryID"
136:
DataTextField = "CategoryName" />
137:
</EditItemTemplate>
138:
</asp:TemplateColumn>
Page_Load()イベントの行9では、Sub LoadData()を呼び出して商品テーブルと商品区分テーブルをDataSetに格納しています。行11では、Sub BindDataGrid()を呼び出して、DataGridに商品テーブルをバインドしています。
8: Sub Page_Load()
9: LoadData()
10: If Not IsPostBack Then
11: BindDataGrid()
12: End If
13: End Sub
Sub LoadData()の行16-19では、商品テーブルと商品区分テーブルを結合させて商品ID,商品名、商品区分ID、商品区分名を抽出するSQLを生成しています。行20-21では、商品区分テーブルからすべてのフィールドを抽出するSQLを生成しています。行22-23では、OleDbConnectionのインスタンスを生成しています。引数には、Web.configに登録されているデータベース接続情報を指定しています。
行27では、OleDbDataAdapterのインスタンスを生成しています。引数には、商品テーブルと商品区分を結合させたSQLとOleDbConnectionを指定しています。行28では、OleDbDataAdapterのFill()メソッドでSQLのSelectステートメントを実行して商品テーブル+商品区分テーブルを抽出してDataSetに格納しています。行29では、OleDbDataAdapterのSelectCommandプロパティにOleDbCommandのインスタンスを設定しています。OleDbCommandの引数には、商品区分テーブルのレコードを抽出するSQLとOleDbConnectionを設定しています。行30では、OleDbDataAdapterのFill()メソッドで、商品区分テーブルを抽出してDataSetに格納しています。これで、DataSetには商品テーブル+商品区分テーブルと商品区分テーブルが格納されます。
15: Sub LoadData()
16: Dim strSqlProduct as String =
"Select p.ProductID, p.ProductName, " & _
17: "c.CategoryID,
c.CategoryName " & _
18: "From Categories
AS c Inner Join Products AS p " & _
19: "On
c.CategoryID=p.CategoryID Order by p.ProductID"
20: Dim strSqlCategory as String =
"Select * From Categories " & _
21: "Order by
CategoryID"
22: Dim con as New OleDbConnection( _
23:
ConfigurationSettings.AppSettings("conStringNw"))
24: Dim da As OleDbDataAdapter
25:
26: mds = New DataSet()
27: da = New
OleDbDataAdapter(strSqlProduct, con)
28: da.Fill(mds, "Products")
29: da.SelectCommand = New OleDbCommand(strSqlCategory,
con)
30: da.Fill(mds,
"Categories")
31: End Sub
Sub BindDataGrid()の行36では、DataGridのDataSourceプロパティに商品テーブルのDataTableを生成して設定しています。行37では、DataBind()メソッドで商品テーブルをバインドして表示しています。
33: Sub BindDataGrid()
34: With dgrdProducts
35: .DataKeyField="ProductID"
36: .DataSource =
mds.Tables("Products")
37: .DataBind()
38: End With
39: End Sub
DataGridのDataBind()メソッドを実行すると、OnItemDataBound()イベントが発生します。このイベントでは、DropDownListのデフォルト値を設定しています。行43-46は、DataGridのItemTypeがEditItemのときに実行されます。行43では、FindControl()メソッドを使用してDropDownListを検索しています。行44-45では、DataItemプロパティからDataRowViewを生成して商品区分IDを取得しています。行46では、DropDownListのListItemコレクションのFindByValue()メソッドを使用してDropDownListのListItemコレクションを検索しています。FindByValue()メソッドは、ListItemのValueプロパティを検索して目的のListItemを見つけます。FindByText()メソッドは、ListItemのTextプロパティを検索して目的のListItemを見つけます。
Response.Write( CType(dropCategory.Items.FindByValue(“1”), ListItem).Text ) è 飲料
Response.Write( CType(dropCategory.Items.FindByText(“飲料”),ListItem).Vaue) è 1
ListItemコレクションのIndexOf()メソッドは、ListItemコレクションからListItemを検索してインデックス番号を返します。
Response.Write( dropCategory.Items.IndexOf( dropCategory.Items.FindByValue("1") ) ) è 0
IndexOf()メッドで取得したインデックス番号をDropDownListのSelectedIndexプロパティに設定してデフォルト値を設定しています。これでレコードの商品区分IDとDropDownListに表示される商品区分名が連動します。
ListItemコレクションのFindByValue(), FindByText(), IndexOf()メソッドは、CheckBoxList, RadioButtonListなどでも使用することができます。
41: Sub dgrdProducts_ItemDataBound(s As Object, e As
DataGridItemEventArgs)
42: If e.Item.ItemType =
ListItemType.EditItem Then
43: Dim dropCategory As
DropDownList = CType(e.Item.FindControl("dropCategories"),
DropDownList)
44: Dim drvProduct As
DataRowView = CType(e.Item.DataItem, DataRowView)
45: Dim strCategoryID As
String = drvProduct("CategoryID").ToString()
46: dropCategory.SelectedIndex=dropCategory.Items.IndexOf(
dropCategory.Items.FindByValue(strCategoryID))
47: End If
48: End Sub
DataGridから編集ボタンをクリックすると、DataGridのOnEditCommandイベントが発生します。このイベントでは、DataGridのEditItemIndexプロパティに編集行のインデックス番号を設定して編集モードに切り替えています。Sub BindDataGrid()を呼び出して、DataGridのDataBind()メソッドを実行するとEditItemIndexに設定されている行が編集行として表示されます。DropDownListには、レコードの商品区分IDと連動する商品区分名がデフォルトとして表示されます。
63: Sub dgrdProducts_EditCommand(s As Object, e As
DataGridCommandEventArgs)
64: dgrdProducts.EditItemIndex =
e.Item.ItemIndex
65: BindDataGrid()
66: End Sub
編集行の確定(更新)ボタンをクリックすると、DataGridのOnUpdateCommandイベントが発生します。このイベントでは、DropDownListから商品区分IDを取得して商品レコードを更新しています。行75では、DataGridのDataKeysプロパティから主キー(ProductID)の値を取得しています。行76-77では、FindControl()メソッドでDropDownListを検索してSelectedItem.Valueプロパティから商品区分IDを取得しています。行79-82のWith…End Withでは、SQLのUpdateステートメントのパラメータに値を設定しています。行84-86では、OleDbCommandのExecuteNonQuery()メソッドでUpdateステートメントを実行して商品テーブルのレコードを更新しています。
68: Sub dgrdProducts_UpdateCommand(s As Object, e As
DataGridCommandEventArgs)
::::
75: Dim
intProductID As Integer = dgrdProducts.DataKeys(e.Item.ItemIndex)
76: Dim
dropCategories As DropDownList =
CType(e.Item.FindControl("dropCategories"), DropDownList)
77: Dim
strCategoryID As String = dropCategories.SelectedItem.Value
79: With
cmd.Parameters
80:
.Add("@CategoryID",strCategoryID)
81:
.Add("@ProductID",intProductID)
82: End With
::::
84: con.Open()
85: cmd.ExecuteNonQuery()
86: con.Close()
:::
91: End Sub