QA@IT
«回答へ戻る

読みにくかったので少し見出し代わりに強調文字を追加

5599
 閉じたようですが、こういうやり方もあるという事で一応残しておきます。
 
+
+**画像チェックボックス**
+
 画像のチェックボックスの部分は
 http://stackoverflow.com/questions/16352864/how-to-display-image-in-place-of-checkbox
 を参考にさせてもらいました(画像リソースも上記サイトのものを借りてしまっていますので、必要に応じてpngファイルをローカルに保存するなどしてください)。
 
+**ソート部分**
+
 1点 注意として、ここではサーバーに返らずにソートする部分を簡易に実現するためにGridViewの
 `EnableSortingAndPagingCallbacks="true"`と`AllowSorting="true"`を使って実現しています。
 このため、ソート時に表内のセルのIDの振り直しとセルの内容の復元(ページ表示時の状態に戻る)が起こります。
 IDの振り直しは レコードのキーを追加 しておいて対応していますが、ソートするとチェック状態が戻ってしまいます(サーバーにはアクセスしていません)。これは javascript でソートする様になれば回避できる問題ですので申し訳ないですがサンプルの簡易化のためにこうさせてもらっています。
 
-
 javascriptによるソートに関してですが、GridViewに特化したものもあるようです。
 
 http://www.codeproject.com/Articles/30287/Sorting-Gridview-using-Jquery-with-ASP-NET
 
 ---
 
+**チェック状態のサーバーへの返却部分について**
+
 このサンプルでは動的にGridViewに追加したコントロールをボタンが押された時のPostBack時に、Request.Formから探して情報を取り出しています。
 ASP.NETコントロールとしてというよりは、HTMLのエレメントとして取り出しています。
 
 `Page.RegisterHiddenField`で hiddenフィールド必要な分だけ作成してPostBack時にRequest.Formから取り出すといった方法もあります。(RegisterHiddenFieldの方が作成した時に指定した名前(name属性)を後でそのまま使えるのできれいにかけるかもしれません)
 
 
+**サンプル**
+
 前置きが長くなりましたが以下がサンプルコードです。
 チェックを付け外しして、ボタンを押すとバインドされているチェックと比べてどのように変化したかがテキストエリアに表示されます。
 ( キー: 変化した値 <== 元の値 という形で出ます。)
     }
 }
 ```
+
+以上、ご参考までに。

閉じたようですが、こういうやり方もあるという事で一応残しておきます。

画像チェックボックス

画像のチェックボックスの部分は
http://stackoverflow.com/questions/16352864/how-to-display-image-in-place-of-checkbox
を参考にさせてもらいました(画像リソースも上記サイトのものを借りてしまっていますので、必要に応じてpngファイルをローカルに保存するなどしてください)。

ソート部分

1点 注意として、ここではサーバーに返らずにソートする部分を簡易に実現するためにGridViewの
EnableSortingAndPagingCallbacks="true"AllowSorting="true"を使って実現しています。
このため、ソート時に表内のセルのIDの振り直しとセルの内容の復元(ページ表示時の状態に戻る)が起こります。
IDの振り直しは レコードのキーを追加 しておいて対応していますが、ソートするとチェック状態が戻ってしまいます(サーバーにはアクセスしていません)。これは javascript でソートする様になれば回避できる問題ですので申し訳ないですがサンプルの簡易化のためにこうさせてもらっています。

javascriptによるソートに関してですが、GridViewに特化したものもあるようです。

http://www.codeproject.com/Articles/30287/Sorting-Gridview-using-Jquery-with-ASP-NET

http://www.codeproject.com/Articles/30011/Sortable-GridView-using-jQuery-s-TableSorter

どちらが良いというわけではなくただの補足です。


チェック状態のサーバーへの返却部分について

このサンプルでは動的にGridViewに追加したコントロールをボタンが押された時のPostBack時に、Request.Formから探して情報を取り出しています。
ASP.NETコントロールとしてというよりは、HTMLのエレメントとして取り出しています。

これ以外ではaspx側でjavascriptを使ってあらかじめ配置していた Hiddenコントロールに後で解析できるように値を詰めてPostBack時に分解する方法や、
Page.RegisterHiddenFieldで hiddenフィールド必要な分だけ作成してPostBack時にRequest.Formから取り出すといった方法もあります。(RegisterHiddenFieldの方が作成した時に指定した名前(name属性)を後でそのまま使えるのできれいにかけるかもしれません)

サンプル

前置きが長くなりましたが以下がサンプルコードです。
チェックを付け外しして、ボタンを押すとバインドされているチェックと比べてどのように変化したかがテキストエリアに表示されます。
( キー: 変化した値 <== 元の値 という形で出ます。)

テーブル名、列名、データソース名は合わせたつもりです。ただしselectしている列の数は違いますのでお気を付けください。

WebForm1.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="QaAtItWeb.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <style>
        /* http://stackoverflow.com/questions/16352864/how-to-display-image-in-place-of-checkbox を利用させてもらっています */
        .checkbox{
            width: 23px;
            height: 21px;
             background: transparent url(http://i.stack.imgur.com/S4p2R.png ) no-repeat 0 50%;
        }
        .checked{
            background: transparent url(http://i.stack.imgur.com/S4p2R.png ) no-repeat 80% 50%;
        }


        span.checkbox input[type="checkbox"] {
            visibility: hidden;
        }
        input[type="text"].checkbox {
            visibility: hidden;
        }
    </style>
    <!-- jqueryのモジュールは googleから取得しています -->
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script>
        $(document).ready(function () {
            //ページ読み込み後の処理


            // ViewStateによりページの状態が復元されるのでそれに合わせてイメージチェックボックスの状態も同期させます。

            $('span.checkbox input[type="checkbox"]').each(function () {
                if ($(this).prop("checked")) {
                    $(this).closest("span").addClass("checked");
                } else {
                    $(this).closest("span").removeClass("checked");
                }
            });


            // イメージチェックボックスのクリックイベント
            $("form").on("click", "span.checkbox", function () {
                $(this).toggleClass('checked')
                if ($(this).hasClass('checked')) {
                    $("input", this).prop('checked', true);
                } else {
                    $("input", this).prop('checked', false);
                }
            });

        });

    </script>
</head>
<body>

    <form id="form1" runat="server">
    <div> 
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="t1" DataSourceID="SqlDataSource1" AllowSorting="true" EnableSortingAndPagingCallbacks="true" OnRowCreated="GridView1_RowCreated">
            <Columns>
                <asp:BoundField DataField="t1" HeaderText="t1" ReadOnly="True" SortExpression="t1" />
                <asp:BoundField DataField="t2" HeaderText="t2" SortExpression="t2" />
                <asp:BoundField DataField="ch" HeaderText="ch" SortExpression="ch" />
                <asp:CheckBoxField HeaderText="ImgCheck" SortExpression="chBit" />
                <asp:CheckBoxField DataField="chBit" HeaderText="元の値" SortExpression="chBit" />
            </Columns>
        </asp:GridView>
        <asp:Button ID="Button1" runat="server" Text="Button" /><br />
        <asp:TextBox ID="TextBox1" runat="server" TextMode="MultiLine" Height="100px"></asp:TextBox>

        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:testdbConnectionString %>" SelectCommand="SELECT [t1], [t2], [ch], [chBit] FROM [tbl001]"></asp:SqlDataSource>

    </div>
    </form>

</body>
</html>

WebForm1.aspx.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace QaAtItWeb
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

            if(IsPostBack){
                TextBox1.Text = "";

                foreach (GridViewRow r in GridView1.Rows)
                {
                    // チェックボックスの変化を表示
                    // 実際にはここで取得するような情報でDBの更新などを行えばよいと思います。



                    // ループ中に検索しているのでよくないコードですが、コードが長くならないようにこうしています。

                    var key = Page.Request.Form.AllKeys
                                .Where(x => x.EndsWith("checkbox_key_" + r.RowIndex.ToString()))
                                .FirstOrDefault();

                    var val=Page.Request.Form.AllKeys
                                .Where(x => x.EndsWith("checkbox_" + r.RowIndex.ToString()))
                                .FirstOrDefault();

                    // 状態の初期値
                    var newState = "off";

                    if (val != null) {
                        newState = Request.Form[val];
                    }

                    TextBox1.Text +=
                        String.Format("{0} :  {2}  <==  {1} \r\n",
                            Request.Form[key],
                            ((CheckBox)r.Cells[4].Controls[0]).Checked,
                            newState);

                }

                GridView1.DataBind();
            }


        }

        protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
        {

            if (e.Row.RowIndex >= 0)
            {
                DataRowView d = (DataRowView)e.Row.DataItem;
                if (d == null) return;


                // イメージチェックボックス用のオブジェクトの追加

                if (d.Row["chBit"] != DBNull.Value)
                {
                    var cb = new CheckBox();
                    // IDを自分で設定しておき、POSTBACK時に取得する際に利用する。
                    cb.ID = "checkbox_" + e.Row.RowIndex.ToString();
                    e.Row.Cells[3].Controls.Add(cb);

                    if ((bool)d.Row["chBit"] == true)
                    {
                        cb.Checked = true;
                        cb.CssClass = "checkbox checked";
                    }
                    else
                    {
                        cb.Checked = false;
                        cb.CssClass = "checkbox";
                    }
                }

                // レコードのキーを追加 ( EnableSortingAndPagingCallbacksでソートしているために )
                var keytext = new TextBox();
                keytext.ID = "checkbox_key_" + e.Row.RowIndex.ToString();

                keytext.Text = d.Row["t1"].ToString();
                keytext.CssClass = "checkbox";
                e.Row.Cells[3].Controls.Add(keytext);

            }
        }

    }
}

以上、ご参考までに。

閉じたようですが、こういうやり方もあるという事で一応残しておきます。


**画像チェックボックス**

画像のチェックボックスの部分は
http://stackoverflow.com/questions/16352864/how-to-display-image-in-place-of-checkbox
を参考にさせてもらいました(画像リソースも上記サイトのものを借りてしまっていますので、必要に応じてpngファイルをローカルに保存するなどしてください)。

**ソート部分**

1点 注意として、ここではサーバーに返らずにソートする部分を簡易に実現するためにGridViewの
`EnableSortingAndPagingCallbacks="true"`と`AllowSorting="true"`を使って実現しています。
このため、ソート時に表内のセルのIDの振り直しとセルの内容の復元(ページ表示時の状態に戻る)が起こります。
IDの振り直しは レコードのキーを追加 しておいて対応していますが、ソートするとチェック状態が戻ってしまいます(サーバーにはアクセスしていません)。これは javascript でソートする様になれば回避できる問題ですので申し訳ないですがサンプルの簡易化のためにこうさせてもらっています。

javascriptによるソートに関してですが、GridViewに特化したものもあるようです。

http://www.codeproject.com/Articles/30287/Sorting-Gridview-using-Jquery-with-ASP-NET

http://www.codeproject.com/Articles/30011/Sortable-GridView-using-jQuery-s-TableSorter

どちらが良いというわけではなくただの補足です。

---

**チェック状態のサーバーへの返却部分について**

このサンプルでは動的にGridViewに追加したコントロールをボタンが押された時のPostBack時に、Request.Formから探して情報を取り出しています。
ASP.NETコントロールとしてというよりは、HTMLのエレメントとして取り出しています。


これ以外ではaspx側でjavascriptを使ってあらかじめ配置していた Hiddenコントロールに後で解析できるように値を詰めてPostBack時に分解する方法や、
`Page.RegisterHiddenField`で hiddenフィールド必要な分だけ作成してPostBack時にRequest.Formから取り出すといった方法もあります。(RegisterHiddenFieldの方が作成した時に指定した名前(name属性)を後でそのまま使えるのできれいにかけるかもしれません)


**サンプル**

前置きが長くなりましたが以下がサンプルコードです。
チェックを付け外しして、ボタンを押すとバインドされているチェックと比べてどのように変化したかがテキストエリアに表示されます。
( キー: 変化した値 <== 元の値 という形で出ます。)


テーブル名、列名、データソース名は合わせたつもりです。ただしselectしている列の数は違いますのでお気を付けください。


**WebForm1.aspx**
```html
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="QaAtItWeb.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <style>
        /* http://stackoverflow.com/questions/16352864/how-to-display-image-in-place-of-checkbox を利用させてもらっています */
        .checkbox{
            width: 23px;
            height: 21px;
             background: transparent url(http://i.stack.imgur.com/S4p2R.png ) no-repeat 0 50%;
        }
        .checked{
            background: transparent url(http://i.stack.imgur.com/S4p2R.png ) no-repeat 80% 50%;
        }


        span.checkbox input[type="checkbox"] {
            visibility: hidden;
        }
        input[type="text"].checkbox {
            visibility: hidden;
        }
    </style>
    <!-- jqueryのモジュールは googleから取得しています -->
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script>
        $(document).ready(function () {
            //ページ読み込み後の処理


            // ViewStateによりページの状態が復元されるのでそれに合わせてイメージチェックボックスの状態も同期させます。

            $('span.checkbox input[type="checkbox"]').each(function () {
                if ($(this).prop("checked")) {
                    $(this).closest("span").addClass("checked");
                } else {
                    $(this).closest("span").removeClass("checked");
                }
            });
            

            // イメージチェックボックスのクリックイベント
            $("form").on("click", "span.checkbox", function () {
                $(this).toggleClass('checked')
                if ($(this).hasClass('checked')) {
                    $("input", this).prop('checked', true);
                } else {
                    $("input", this).prop('checked', false);
                }
            });

        });

    </script>
</head>
<body>

    <form id="form1" runat="server">
    <div> 
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="t1" DataSourceID="SqlDataSource1" AllowSorting="true" EnableSortingAndPagingCallbacks="true" OnRowCreated="GridView1_RowCreated">
            <Columns>
                <asp:BoundField DataField="t1" HeaderText="t1" ReadOnly="True" SortExpression="t1" />
                <asp:BoundField DataField="t2" HeaderText="t2" SortExpression="t2" />
                <asp:BoundField DataField="ch" HeaderText="ch" SortExpression="ch" />
                <asp:CheckBoxField HeaderText="ImgCheck" SortExpression="chBit" />
                <asp:CheckBoxField DataField="chBit" HeaderText="元の値" SortExpression="chBit" />
            </Columns>
        </asp:GridView>
        <asp:Button ID="Button1" runat="server" Text="Button" /><br />
        <asp:TextBox ID="TextBox1" runat="server" TextMode="MultiLine" Height="100px"></asp:TextBox>

        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:testdbConnectionString %>" SelectCommand="SELECT [t1], [t2], [ch], [chBit] FROM [tbl001]"></asp:SqlDataSource>
    
    </div>
    </form>
    
</body>
</html>
```

**WebForm1.aspx.cs**
```csharp
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace QaAtItWeb
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

            if(IsPostBack){
                TextBox1.Text = "";

                foreach (GridViewRow r in GridView1.Rows)
                {
                    // チェックボックスの変化を表示
                    // 実際にはここで取得するような情報でDBの更新などを行えばよいと思います。



                    // ループ中に検索しているのでよくないコードですが、コードが長くならないようにこうしています。

                    var key = Page.Request.Form.AllKeys
                                .Where(x => x.EndsWith("checkbox_key_" + r.RowIndex.ToString()))
                                .FirstOrDefault();

                    var val=Page.Request.Form.AllKeys
                                .Where(x => x.EndsWith("checkbox_" + r.RowIndex.ToString()))
                                .FirstOrDefault();

                    // 状態の初期値
                    var newState = "off";

                    if (val != null) {
                        newState = Request.Form[val];
                    }

                    TextBox1.Text +=
                        String.Format("{0} :  {2}  <==  {1} \r\n",
                            Request.Form[key],
                            ((CheckBox)r.Cells[4].Controls[0]).Checked,
                            newState);
                    
                }

                GridView1.DataBind();
            }


        }

        protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
        {

            if (e.Row.RowIndex >= 0)
            {
                DataRowView d = (DataRowView)e.Row.DataItem;
                if (d == null) return;


                // イメージチェックボックス用のオブジェクトの追加

                if (d.Row["chBit"] != DBNull.Value)
                {
                    var cb = new CheckBox();
                    // IDを自分で設定しておき、POSTBACK時に取得する際に利用する。
                    cb.ID = "checkbox_" + e.Row.RowIndex.ToString();
                    e.Row.Cells[3].Controls.Add(cb);

                    if ((bool)d.Row["chBit"] == true)
                    {
                        cb.Checked = true;
                        cb.CssClass = "checkbox checked";
                    }
                    else
                    {
                        cb.Checked = false;
                        cb.CssClass = "checkbox";
                    }
                }

                // レコードのキーを追加 ( EnableSortingAndPagingCallbacksでソートしているために )
                var keytext = new TextBox();
                keytext.ID = "checkbox_key_" + e.Row.RowIndex.ToString();

                keytext.Text = d.Row["t1"].ToString();
                keytext.CssClass = "checkbox";
                e.Row.Cells[3].Controls.Add(keytext);

            }
        }

    }
}
```

以上、ご参考までに。

回答を投稿

閉じたようですが、こういうやり方もあるという事で一応残しておきます。

画像のチェックボックスの部分は
http://stackoverflow.com/questions/16352864/how-to-display-image-in-place-of-checkbox
を参考にさせてもらいました(画像リソースも上記サイトのものを借りてしまっていますので、必要に応じてpngファイルをローカルに保存するなどしてください)。

1点 注意として、ここではサーバーに返らずにソートする部分を簡易に実現するためにGridViewの
EnableSortingAndPagingCallbacks="true"AllowSorting="true"を使って実現しています。
このため、ソート時に表内のセルのIDの振り直しとセルの内容の復元(ページ表示時の状態に戻る)が起こります。
IDの振り直しは レコードのキーを追加 しておいて対応していますが、ソートするとチェック状態が戻ってしまいます(サーバーにはアクセスしていません)。これは javascript でソートする様になれば回避できる問題ですので申し訳ないですがサンプルの簡易化のためにこうさせてもらっています。

javascriptによるソートに関してですが、GridViewに特化したものもあるようです。

http://www.codeproject.com/Articles/30287/Sorting-Gridview-using-Jquery-with-ASP-NET

http://www.codeproject.com/Articles/30011/Sortable-GridView-using-jQuery-s-TableSorter

どちらが良いというわけではなくただの補足です。


このサンプルでは動的にGridViewに追加したコントロールをボタンが押された時のPostBack時に、Request.Formから探して情報を取り出しています。
ASP.NETコントロールとしてというよりは、HTMLのエレメントとして取り出しています。

これ以外ではaspx側でjavascriptを使ってあらかじめ配置していた Hiddenコントロールに後で解析できるように値を詰めてPostBack時に分解する方法や、
Page.RegisterHiddenFieldで hiddenフィールド必要な分だけ作成してPostBack時にRequest.Formから取り出すといった方法もあります。(RegisterHiddenFieldの方が作成した時に指定した名前(name属性)を後でそのまま使えるのできれいにかけるかもしれません)

前置きが長くなりましたが以下がサンプルコードです。
チェックを付け外しして、ボタンを押すとバインドされているチェックと比べてどのように変化したかがテキストエリアに表示されます。
( キー: 変化した値 <== 元の値 という形で出ます。)

テーブル名、列名、データソース名は合わせたつもりです。ただしselectしている列の数は違いますのでお気を付けください。

WebForm1.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="QaAtItWeb.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <style>
        /* http://stackoverflow.com/questions/16352864/how-to-display-image-in-place-of-checkbox を利用させてもらっています */
        .checkbox{
            width: 23px;
            height: 21px;
             background: transparent url(http://i.stack.imgur.com/S4p2R.png ) no-repeat 0 50%;
        }
        .checked{
            background: transparent url(http://i.stack.imgur.com/S4p2R.png ) no-repeat 80% 50%;
        }


        span.checkbox input[type="checkbox"] {
            visibility: hidden;
        }
        input[type="text"].checkbox {
            visibility: hidden;
        }
    </style>
    <!-- jqueryのモジュールは googleから取得しています -->
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script>
        $(document).ready(function () {
            //ページ読み込み後の処理


            // ViewStateによりページの状態が復元されるのでそれに合わせてイメージチェックボックスの状態も同期させます。

            $('span.checkbox input[type="checkbox"]').each(function () {
                if ($(this).prop("checked")) {
                    $(this).closest("span").addClass("checked");
                } else {
                    $(this).closest("span").removeClass("checked");
                }
            });


            // イメージチェックボックスのクリックイベント
            $("form").on("click", "span.checkbox", function () {
                $(this).toggleClass('checked')
                if ($(this).hasClass('checked')) {
                    $("input", this).prop('checked', true);
                } else {
                    $("input", this).prop('checked', false);
                }
            });

        });

    </script>
</head>
<body>

    <form id="form1" runat="server">
    <div> 
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="t1" DataSourceID="SqlDataSource1" AllowSorting="true" EnableSortingAndPagingCallbacks="true" OnRowCreated="GridView1_RowCreated">
            <Columns>
                <asp:BoundField DataField="t1" HeaderText="t1" ReadOnly="True" SortExpression="t1" />
                <asp:BoundField DataField="t2" HeaderText="t2" SortExpression="t2" />
                <asp:BoundField DataField="ch" HeaderText="ch" SortExpression="ch" />
                <asp:CheckBoxField HeaderText="ImgCheck" SortExpression="chBit" />
                <asp:CheckBoxField DataField="chBit" HeaderText="元の値" SortExpression="chBit" />
            </Columns>
        </asp:GridView>
        <asp:Button ID="Button1" runat="server" Text="Button" /><br />
        <asp:TextBox ID="TextBox1" runat="server" TextMode="MultiLine" Height="100px"></asp:TextBox>

        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:testdbConnectionString %>" SelectCommand="SELECT [t1], [t2], [ch], [chBit] FROM [tbl001]"></asp:SqlDataSource>

    </div>
    </form>

</body>
</html>

WebForm1.aspx.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace QaAtItWeb
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

            if(IsPostBack){
                TextBox1.Text = "";

                foreach (GridViewRow r in GridView1.Rows)
                {
                    // チェックボックスの変化を表示
                    // 実際にはここで取得するような情報でDBの更新などを行えばよいと思います。



                    // ループ中に検索しているのでよくないコードですが、コードが長くならないようにこうしています。

                    var key = Page.Request.Form.AllKeys
                                .Where(x => x.EndsWith("checkbox_key_" + r.RowIndex.ToString()))
                                .FirstOrDefault();

                    var val=Page.Request.Form.AllKeys
                                .Where(x => x.EndsWith("checkbox_" + r.RowIndex.ToString()))
                                .FirstOrDefault();

                    // 状態の初期値
                    var newState = "off";

                    if (val != null) {
                        newState = Request.Form[val];
                    }

                    TextBox1.Text +=
                        String.Format("{0} :  {2}  <==  {1} \r\n",
                            Request.Form[key],
                            ((CheckBox)r.Cells[4].Controls[0]).Checked,
                            newState);

                }

                GridView1.DataBind();
            }


        }

        protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
        {

            if (e.Row.RowIndex >= 0)
            {
                DataRowView d = (DataRowView)e.Row.DataItem;
                if (d == null) return;


                // イメージチェックボックス用のオブジェクトの追加

                if (d.Row["chBit"] != DBNull.Value)
                {
                    var cb = new CheckBox();
                    // IDを自分で設定しておき、POSTBACK時に取得する際に利用する。
                    cb.ID = "checkbox_" + e.Row.RowIndex.ToString();
                    e.Row.Cells[3].Controls.Add(cb);

                    if ((bool)d.Row["chBit"] == true)
                    {
                        cb.Checked = true;
                        cb.CssClass = "checkbox checked";
                    }
                    else
                    {
                        cb.Checked = false;
                        cb.CssClass = "checkbox";
                    }
                }

                // レコードのキーを追加 ( EnableSortingAndPagingCallbacksでソートしているために )
                var keytext = new TextBox();
                keytext.ID = "checkbox_key_" + e.Row.RowIndex.ToString();

                keytext.Text = d.Row["t1"].ToString();
                keytext.CssClass = "checkbox";
                e.Row.Cells[3].Controls.Add(keytext);

            }
        }

    }
}
閉じたようですが、こういうやり方もあるという事で一応残しておきます。

画像のチェックボックスの部分は
http://stackoverflow.com/questions/16352864/how-to-display-image-in-place-of-checkbox
を参考にさせてもらいました(画像リソースも上記サイトのものを借りてしまっていますので、必要に応じてpngファイルをローカルに保存するなどしてください)。

1点 注意として、ここではサーバーに返らずにソートする部分を簡易に実現するためにGridViewの
`EnableSortingAndPagingCallbacks="true"`と`AllowSorting="true"`を使って実現しています。
このため、ソート時に表内のセルのIDの振り直しとセルの内容の復元(ページ表示時の状態に戻る)が起こります。
IDの振り直しは レコードのキーを追加 しておいて対応していますが、ソートするとチェック状態が戻ってしまいます(サーバーにはアクセスしていません)。これは javascript でソートする様になれば回避できる問題ですので申し訳ないですがサンプルの簡易化のためにこうさせてもらっています。


javascriptによるソートに関してですが、GridViewに特化したものもあるようです。

http://www.codeproject.com/Articles/30287/Sorting-Gridview-using-Jquery-with-ASP-NET

http://www.codeproject.com/Articles/30011/Sortable-GridView-using-jQuery-s-TableSorter

どちらが良いというわけではなくただの補足です。

---

このサンプルでは動的にGridViewに追加したコントロールをボタンが押された時のPostBack時に、Request.Formから探して情報を取り出しています。
ASP.NETコントロールとしてというよりは、HTMLのエレメントとして取り出しています。


これ以外ではaspx側でjavascriptを使ってあらかじめ配置していた Hiddenコントロールに後で解析できるように値を詰めてPostBack時に分解する方法や、
`Page.RegisterHiddenField`で hiddenフィールド必要な分だけ作成してPostBack時にRequest.Formから取り出すといった方法もあります。(RegisterHiddenFieldの方が作成した時に指定した名前(name属性)を後でそのまま使えるのできれいにかけるかもしれません)


前置きが長くなりましたが以下がサンプルコードです。
チェックを付け外しして、ボタンを押すとバインドされているチェックと比べてどのように変化したかがテキストエリアに表示されます。
( キー: 変化した値 <== 元の値 という形で出ます。)


テーブル名、列名、データソース名は合わせたつもりです。ただしselectしている列の数は違いますのでお気を付けください。


**WebForm1.aspx**
```html
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="QaAtItWeb.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <style>
        /* http://stackoverflow.com/questions/16352864/how-to-display-image-in-place-of-checkbox を利用させてもらっています */
        .checkbox{
            width: 23px;
            height: 21px;
             background: transparent url(http://i.stack.imgur.com/S4p2R.png ) no-repeat 0 50%;
        }
        .checked{
            background: transparent url(http://i.stack.imgur.com/S4p2R.png ) no-repeat 80% 50%;
        }


        span.checkbox input[type="checkbox"] {
            visibility: hidden;
        }
        input[type="text"].checkbox {
            visibility: hidden;
        }
    </style>
    <!-- jqueryのモジュールは googleから取得しています -->
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script>
        $(document).ready(function () {
            //ページ読み込み後の処理


            // ViewStateによりページの状態が復元されるのでそれに合わせてイメージチェックボックスの状態も同期させます。

            $('span.checkbox input[type="checkbox"]').each(function () {
                if ($(this).prop("checked")) {
                    $(this).closest("span").addClass("checked");
                } else {
                    $(this).closest("span").removeClass("checked");
                }
            });
            

            // イメージチェックボックスのクリックイベント
            $("form").on("click", "span.checkbox", function () {
                $(this).toggleClass('checked')
                if ($(this).hasClass('checked')) {
                    $("input", this).prop('checked', true);
                } else {
                    $("input", this).prop('checked', false);
                }
            });

        });

    </script>
</head>
<body>

    <form id="form1" runat="server">
    <div> 
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="t1" DataSourceID="SqlDataSource1" AllowSorting="true" EnableSortingAndPagingCallbacks="true" OnRowCreated="GridView1_RowCreated">
            <Columns>
                <asp:BoundField DataField="t1" HeaderText="t1" ReadOnly="True" SortExpression="t1" />
                <asp:BoundField DataField="t2" HeaderText="t2" SortExpression="t2" />
                <asp:BoundField DataField="ch" HeaderText="ch" SortExpression="ch" />
                <asp:CheckBoxField HeaderText="ImgCheck" SortExpression="chBit" />
                <asp:CheckBoxField DataField="chBit" HeaderText="元の値" SortExpression="chBit" />
            </Columns>
        </asp:GridView>
        <asp:Button ID="Button1" runat="server" Text="Button" /><br />
        <asp:TextBox ID="TextBox1" runat="server" TextMode="MultiLine" Height="100px"></asp:TextBox>

        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:testdbConnectionString %>" SelectCommand="SELECT [t1], [t2], [ch], [chBit] FROM [tbl001]"></asp:SqlDataSource>
    
    </div>
    </form>
    
</body>
</html>
```

**WebForm1.aspx.cs**
```csharp
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace QaAtItWeb
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

            if(IsPostBack){
                TextBox1.Text = "";

                foreach (GridViewRow r in GridView1.Rows)
                {
                    // チェックボックスの変化を表示
                    // 実際にはここで取得するような情報でDBの更新などを行えばよいと思います。



                    // ループ中に検索しているのでよくないコードですが、コードが長くならないようにこうしています。

                    var key = Page.Request.Form.AllKeys
                                .Where(x => x.EndsWith("checkbox_key_" + r.RowIndex.ToString()))
                                .FirstOrDefault();

                    var val=Page.Request.Form.AllKeys
                                .Where(x => x.EndsWith("checkbox_" + r.RowIndex.ToString()))
                                .FirstOrDefault();

                    // 状態の初期値
                    var newState = "off";

                    if (val != null) {
                        newState = Request.Form[val];
                    }

                    TextBox1.Text +=
                        String.Format("{0} :  {2}  <==  {1} \r\n",
                            Request.Form[key],
                            ((CheckBox)r.Cells[4].Controls[0]).Checked,
                            newState);
                    
                }

                GridView1.DataBind();
            }


        }

        protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
        {

            if (e.Row.RowIndex >= 0)
            {
                DataRowView d = (DataRowView)e.Row.DataItem;
                if (d == null) return;


                // イメージチェックボックス用のオブジェクトの追加

                if (d.Row["chBit"] != DBNull.Value)
                {
                    var cb = new CheckBox();
                    // IDを自分で設定しておき、POSTBACK時に取得する際に利用する。
                    cb.ID = "checkbox_" + e.Row.RowIndex.ToString();
                    e.Row.Cells[3].Controls.Add(cb);

                    if ((bool)d.Row["chBit"] == true)
                    {
                        cb.Checked = true;
                        cb.CssClass = "checkbox checked";
                    }
                    else
                    {
                        cb.Checked = false;
                        cb.CssClass = "checkbox";
                    }
                }

                // レコードのキーを追加 ( EnableSortingAndPagingCallbacksでソートしているために )
                var keytext = new TextBox();
                keytext.ID = "checkbox_key_" + e.Row.RowIndex.ToString();

                keytext.Text = d.Row["t1"].ToString();
                keytext.CssClass = "checkbox";
                e.Row.Cells[3].Controls.Add(keytext);

            }
        }

    }
}
```