GridView で INSERT 操作(データベースにレコードを追加)する方法の紹介です。そもそも、GridView にはデータベースにレコードを追加する機能はありませんが、そこを無理やりその機能を追加するという話です。
参考にさせていただいたのは GridView からデータを追加する です。参考にしたと言うより、アイデアはほぼそのままコピーさせていただいたのですが。(汗)
データベースにレコードを追加するには、TextBox などのユーザー入力のためのコントロールを GridView のどこかに配置し、ポストバックで送信されてきた値を処置する必要があります。
ユーザー入力のためのコントロールを GridView のどこに配置できるかと言えば、フッター以外に適当な場所はないです。上の画像を見てください。フッター(一番下の行)に[追加]という LinkButton と空白の TextBox が 3 つ配置されているのが分かると思います。
フッターにコントロールを配置するには、デザイン画面の GridView のテンプレートの編集メニューで、各列の FooterTemplate を編集します。
コマンドを送る[追加]ボタンの CommandName プロパティを "Insert" に設定するのがポイントです。そうしておけば、[追加]ボタンがクリックされたことを、GridView.RowCommand イベントのハンドラで判断して処置ができます。
GridView.ShowFooter プロパティを true に設定するのを忘れないようにしてください(デフォルトでは false です)。
この状態で、[追加]ボタンをクリックするとポストバックが発生し、ユーザーが TextBox に入力した値がサーバーに送信されます。
GridView 内のボタンクリックでポストバックされると、サーバー側では GridView.RowCommand イベントが発生しますので、そのイベントハンドラでレコードの追加処置を行います。
具体的には、クリックされたのが[追加]ボタンかどうかを CommandName プロパティから判断し、SqlDataSource の InsertParameters(InsertCommand プロパティで使用されるパラメータを格納するパラメータ コレクション)の内容を、ユーザー入力の TextBox をバインド先に設定した ControlParameter に書き換えます。その後、SqlDataSource.Insert メソッドで挿入操作を実行します。
ここで、ポイントは、ControlParameter コンストラクタの第三引数(パラメータのバインド先のコントロールの名前)に UniqueID を使うことです。そうしないとコントロールが見つからないというエラーになります。
ポストバックで、ユーザーが TextBox(html では <input type="text"... />)に入力した値がサーバーに送信される際、key(name 属性の値)と value(value 属性の値)がペアで送信されますが、この key に UniqueID が使用されますのでそれを利用します。
サーバー側では HttpRequest.Form.AllKeys で key のコレクションが取得できます。コレクションの中の key を一つ一つ調べて、key の値に当該コントロールの ID が含まれていれば、その key の値を ControlParameter コンストラクタの第三引数に使用します。
それが下のサンプルの中の GridView1_RowCommand メソッドのコードです。ここまでで、レコードが一行でも存在すればフッターが表示されますので、レコードの追加を行うことができます。
しかし、レコードが一行も存在しない場合が問題です。何故なら、その場合はフッターも表示されないからです。
その対応としては、レコードが一行も存在しない場合は EmptyDataTemplate が表示されますので、その中に LinkButton や TextBox を配置して使用します。
その際のポイントは、LinkButton の CommandName プロパティを "Insert" に設定するのに加えて、TextBox の ID をフッターに配置したものと同一にしておくことです。
そうすれば、GridView.RowCommand イベントのハンドラ(GridView1_RowCommand メソッド)には一切手を加えることなく、フッターに配置した LinkButton と TextBox と同様に、レコードの追加処置ができます。
具体的には以下のサンプルコードを見てください。
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
// ControlParameter コンストラクタの第三引数(パラメータの
// バインド先のコントロールの名前)に UniqueID を使わないと
// コントロールが見つからないというエラーになる。
protected void GridView1_RowCommand(object sender,
GridViewCommandEventArgs e)
{
if (e.CommandName == "Insert")
{
SqlDataSource1.InsertParameters.Clear();
foreach (string key in Request.Form.AllKeys)
{
if (key.Contains("TextBox4"))
{
SqlDataSource1.InsertParameters.Add(
new ControlParameter(
"name",
TypeCode.String,
key,
"Text"));
}
if (key.Contains("TextBox5"))
{
SqlDataSource1.InsertParameters.Add(
new ControlParameter(
"price",
TypeCode.Decimal,
key,
"Text"));
}
if (key.Contains("TextBox6"))
{
SqlDataSource1.InsertParameters.Add(
new ControlParameter(
"memo",
TypeCode.String,
key,
"Text"));
}
}
SqlDataSource1.Insert();
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:MyDB %>"
DeleteCommand="DELETE FROM [Table] WHERE [id] = @id"
InsertCommand="INSERT INTO [Table] ([name], [price], [memo])
VALUES (@name, @price, @memo)"
SelectCommand="SELECT [id], [name], [price], [memo]
FROM [Table]"
UpdateCommand="UPDATE [Table]
SET [name] = @name, [price] = @price, [memo] = @memo
WHERE [id] = @id">
<DeleteParameters>
<asp:Parameter Name="id" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="name" Type="String" />
<asp:Parameter Name="price" Type="Decimal" />
<asp:Parameter Name="memo" Type="String" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="name" Type="String" />
<asp:Parameter Name="price" Type="Decimal" />
<asp:Parameter Name="memo" Type="String" />
<asp:Parameter Name="id" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
<asp:GridView ID="GridView1"
runat="server"
AutoGenerateColumns="False"
DataKeyNames="id"
DataSourceID="SqlDataSource1"
ShowFooter="True"
OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:TemplateField ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="LinkButton1"
runat="server"
CausesValidation="True"
CommandName="Update"
Text="更新">
</asp:LinkButton>
<asp:LinkButton ID="LinkButton2"
runat="server"
CausesValidation="False"
CommandName="Cancel"
Text="キャンセル">
</asp:LinkButton>
</EditItemTemplate>
<FooterTemplate>
<asp:LinkButton ID="LinkButton3"
runat="server"
CommandName="Insert">
追加
</asp:LinkButton>
</FooterTemplate>
<ItemTemplate>
<asp:LinkButton ID="LinkButton1"
runat="server"
CausesValidation="False"
CommandName="Edit"
Text="編集">
</asp:LinkButton>
<asp:LinkButton ID="LinkButton2"
runat="server"
CausesValidation="False"
CommandName="Delete"
Text="削除">
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="id"
InsertVisible="False"
SortExpression="id">
<EditItemTemplate>
<asp:Label ID="Label1"
runat="server"
Text='<%# Eval("id") %>'>
</asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label4"
runat="server"
Text='<%# Bind("id") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="name"
SortExpression="name">
<EditItemTemplate>
<asp:TextBox ID="TextBox1"
runat="server"
Text='<%# Bind("name") %>'>
</asp:TextBox>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="TextBox4"
runat="server">
</asp:TextBox>
</FooterTemplate>
<ItemTemplate>
<asp:Label ID="Label1"
runat="server"
Text='<%# Bind("name") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="price"
SortExpression="price">
<EditItemTemplate>
<asp:TextBox ID="TextBox2"
runat="server"
Text='<%# Bind("price") %>'>
</asp:TextBox>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="TextBox5"
runat="server">
</asp:TextBox>
</FooterTemplate>
<ItemTemplate>
<asp:Label ID="Label2"
runat="server"
Text='<%# Bind("price") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="memo"
SortExpression="memo">
<EditItemTemplate>
<asp:TextBox ID="TextBox3"
runat="server"
Text='<%# Bind("memo") %>'>
</asp:TextBox>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="TextBox6"
runat="server">
</asp:TextBox>
</FooterTemplate>
<ItemTemplate>
<asp:Label ID="Label3"
runat="server"
Text='<%# Bind("memo") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
<table style="width:100%;">
<tr>
<th> </th>
<th>id</th>
<th>name</th>
<th>price</th>
<th>memo</th>
</tr>
<tr>
<td>
<asp:LinkButton ID="LinkButton3"
runat="server"
CommandName="Insert">
追加
</asp:LinkButton>
</td>
<td>
</td>
<td>
<asp:TextBox ID="TextBox4"
runat="server">
</asp:TextBox>
</td>
<td>
<asp:TextBox ID="TextBox5"
runat="server">
</asp:TextBox>
</td>
<td>
<asp:TextBox ID="TextBox6"
runat="server">
</asp:TextBox>
</td>
</tr>
</table>
</EmptyDataTemplate>
</asp:GridView>
</div>
</form>
</body>
</html>