WebSurfer's Home

トップ > Blog 1   |   Login
Filter by APML

GridView で INSERT 操作

by WebSurfer 30. October 2013 17:27

GridView で INSERT 操作(データベースにレコードを追加)する方法の紹介です。そもそも、GridView にはデータベースにレコードを追加する機能はありませんが、そこを無理やりその機能を追加するという話です。

GridView で INSERT 操作

参考にさせていただいたのは 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>

Tags:

ASP.NET

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  June 2021  >>
MoTuWeThFrSaSu
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar