トップ回答者
ASP.NETでPostgreSQLのデータ表示とCheckBoxFieldの追加

質問
-
VisualStudio2010
.NET Framework 4
PostgreSQL9.2
PostgreSQLのテーブルをGridViewに表示をさせており、
そのGridViewにテーブルのデータとは無関係のCheckBoxFieldを追加させようとしてます。
そのあと、ボタンを押すとチェックされているチェックボックスが判断できるようなものがを作りたいのですが、うまくいきません。
http://www.shise.net/wiki/wiki.cgi?page=C%23%2FPostgreSQL
ODBCでPostgrSQLに接続し、データを取得
http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/16b622d8-43fc-4a17-81ce-8fb92f90ed46/
CheckBox を ItemTemplate に入れるというやり方はできたのですが、
ボタンを押下すると、チェックボックスが消えてしまいます。
どのようにやると実現できるでしょうか?
回答
-
CheckBox を ItemTemplate に入れるというやり方はできたのですが、
ボタンを押下すると、チェックボックスが消えてしまいます。
チェックボックスが消えるというのは、チェックボックスのチェックが外れるということではなく、チェックボックスそのものが消えてしまうということでしょうか?
普通、以下のようにItemTemplateを追加するだけで、ボタンを押してポストバックが発生してもチェックボックスが消えることはありません。<asp:TemplateField> <ItemTemplate> <asp:CheckBox ID="CheckBox1" runat="server" /> </ItemTemplate> </asp:TemplateField>
ボタンはGridViewの外に配置しており、GridViewは編集モードではないということでよろしいでしょうか? その辺りを含め、どのようなコードを書かれているのか、再現する最小のコードを掲載していただくと、解決が早まると思います。
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
- 回答としてマーク AKI1050_ 2013年3月21日 3:32
すべての返信
-
GridView ではなくて ListView を使用した例ですが、以下のページのような感じでいいのかな?
ListView に配置した CheckBox で選択
http://surferonwww.info/BlogEngine/post/2012/03/17/Select-items-by-CheckBox-placed-in-ListView.aspx -
説明不足で、申し訳ないです。
画面上にGridViewとボタンが置いてある状態です。(URLの通りです。)
画面の.aspxです
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="main.aspx.cs" Inherits="PostgresSQLTest.main" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"> <Columns> <asp:BoundField DataField="id" HeaderText="id" /> <asp:BoundField DataField="date" HeaderText="date" /> <asp:BoundField DataField="name" HeaderText="date" /> </Columns> </asp:GridView> <asp:Button ID="Button2" runat="server" onclick="Button2_Click" Text="Button" /> </div> </form> </body> </html>
- 編集済み AKI1050_ 2013年3月21日 2:07
-
CheckBox を ItemTemplate に入れるというやり方はできたのですが、
ボタンを押下すると、チェックボックスが消えてしまいます。
チェックボックスが消えるというのは、チェックボックスのチェックが外れるということではなく、チェックボックスそのものが消えてしまうということでしょうか?
普通、以下のようにItemTemplateを追加するだけで、ボタンを押してポストバックが発生してもチェックボックスが消えることはありません。<asp:TemplateField> <ItemTemplate> <asp:CheckBox ID="CheckBox1" runat="server" /> </ItemTemplate> </asp:TemplateField>
ボタンはGridViewの外に配置しており、GridViewは編集モードではないということでよろしいでしょうか? その辺りを含め、どのようなコードを書かれているのか、再現する最小のコードを掲載していただくと、解決が早まると思います。
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
- 回答としてマーク AKI1050_ 2013年3月21日 3:32
-
列にあるチェックボックスが消えてしまいます。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="main.aspx.cs" Inherits="PostgresSQLTest.main" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"> <Columns> <asp:BoundField DataField="id" HeaderText="id" /> <asp:BoundField DataField="date" HeaderText="date" /> <asp:BoundField DataField="name" HeaderText="name" /> </Columns> </asp:GridView> <asp:Button ID="Button2" runat="server" onclick="Button2_Click" Text="Button" /> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> </div> </form> </body> </html>
コード
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data.Odbc; using System.Data; namespace PostgresSQLTest { public partial class main : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // TemplateField列追加 TemplateField tf = new TemplateField(); tf.HeaderText = "chkBox"; tf.ItemTemplate = new MyItemTemplate(); GridView2.Columns.Add(tf); string myConnection = string.Empty; myConnection += "DSN=PostgreSQL35W_32bit;"; // PostgreSQLのODBCドライバを指定 myConnection += "SERVER=localhost;"; // 接続先 myConnection += "PORT=5432;"; // ポート myConnection += "DATABASE=postgres;"; // データベース名 myConnection += "USERNAME=postgres;"; // 接続ユーザ名 myConnection += "PASSWORD=pass;"; // パスワード // 接続を開く OdbcConnection myConn = new OdbcConnection(myConnection); myConn.Open(); // コマンドの作成 OdbcCommand myOdbcCommand = new OdbcCommand(); myOdbcCommand.Connection = myConn; myOdbcCommand.CommandText = "select * from \"testTable\""; OdbcDataReader reader = myOdbcCommand.ExecuteReader(); DataTable dt = new DataTable(); dt.Load(reader); // チェックボックス列追加 DataColumn colBoolean = new DataColumn("chkBox"); colBoolean.DataType = System.Type.GetType("System.Boolean"); dt.Columns.Add(colBoolean); // チェックボックスをtrue int iLen = dt.Rows.Count; for (int i = 0; i < iLen; i++) { dt.Rows[i][3] = true; } // バインド GridView2.DataSource = dt; GridView2.DataBind(); } } // TemplateFieldの中にチェックボックスを追加 public class MyItemTemplate : ITemplate { public void InstantiateIn(Control container) { CheckBox cb = new CheckBox(); cb.DataBinding += new EventHandler(this.DataBinding); container.Controls.Add(cb); } public void DataBinding(object sender, EventArgs e) { CheckBox cb = (CheckBox)sender; DataRowView dataItem = (DataRowView)((GridViewRow)cb.NamingContainer).DataItem; cb.Checked = (bool)((DataRowView)dataItem)["chkBox"]; } } protected void Button2_Click(object sender, EventArgs e) { int iLen = GridView2.Rows.Count; string strTmp = ""; for (int i = 0; i < iLen; i++) { if (((CheckBox)GridView2.Rows[i].Cells[3].Controls[1]).Checked) { strTmp += i + strTmp + ":"; } } TextBox1.Text = strTmp; } } }
PostgreSQLのテーブルの構造が
CREATE TABLE "testTable"
(
id integer NOT NULL DEFAULT 1,
date date NOT NULL,
name character varying(32) NOT NULL,
CONSTRAINT id PRIMARY KEY (id)
)となっております。
チェックボックスはテーブルの構造にないもので、動的に追加しています。
Button2_Clickの
if (((CheckBox)GridView2.Rows[i].Cells[3].Controls[1]).Checked) {
でエラーが起きてしまい、処理をなくして実行すると、チェックボックスが消えてしまいます。
trapemiyaさんのやり方だと、チェックボックスが灰色になってしまい、オンオフができません。
-
ASP.NETの動作の基本を押さえる必要があります。ASP.NETはポストバックが発生する度に、毎回新しくプログラムが実行されます。つまり、前回実行した結果はどこにも残っていません。リセットされた状態になっているということです。前回実行した結果を今回使いたい場合は、今回使えるように残しておく必要があります。
これを踏まえて、Page_Loadイベントハンドラ内の処理ですが、if (!IsPostBack) {・・・・}の処理は、最初に一度しか実行されません。2回目以降のポストバック時には実行されませんから、当然、チェックボックスは追加されませんし、前回作成したデータテーブルもどこにもありません。
よって、チェックボックスの追加は毎回行う必要があるので、if (!IsPostBack) {・・・・}の外に出します。データテーブルの作成は、if (!IsPostBack) {・・・・}内でかまいませんが、作成した後にSession変数に格納し、2回目以降、つまりポストバック時は、そのSession変数から復元する必要があります。ただ、全体的にコードの整合性が取れていない気がします。
GridViewにしかチェックボックスの値を保持しているところが無い場合は、以下のコードのようにして値を取得するしかありませんが、データテーブルにチェックボックスにバインドする値を保持する列を追加しているのであれば、以下のコードで判断しなくても、データテーブル上の値で判断すれば済むことです。
if (((CheckBox)GridView2.Rows[i].Cells[3].Controls[1]).Checked)データテーブルにチェックボックスにバインドする値を保持しなくても良いのであれば、私が先に挙げたItemTemplateにチェックボックスを配置し、
if (((CheckBox)GridView2.Rows[i].Cells[3].Controls[1]).Checked)
のようにして判断するのが簡単です。
そうではなく、データテーブル上に保持したいのであれば、例えば、
select *, cast(1 as bit) as boolcal from testTable
のように、最初からSQL文で用意してしまうのが簡単でしょう。
そして、私が先に挙げたItemTemplateにチェックボックスを配置し、バインドすればOKです。
チェックボックスがグレーアウトして弄れなくなっている場合は、Enabledがfalseになっていないか等をチェックしてみて下さい。★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
-
> チェックボックスはテーブルの構造にないもので、動的に追加しています。
動的に追加する必要はないはずですが、動的に追加するのであればポストバックの際も動的に追加しないと、ポストバックしたとき消えてしまいます。
> if (((CheckBox)GridView2.Rows[i].Cells[3].Controls[1]).Checked) {
> でエラーが起きてしまい、エラーが起きてしまうというだけでは情報不足です。どういうエラーが出ているか、エラーメッセージをコピペしてください。
たぶん、CheckBox が取得できてないのだと思いますが、その場合、コードで CheckBox に ID を付与して、FindControl メソッドで探すのが確実です。