none
ASP.NETでPostgreSQLのデータ表示とCheckBoxFieldの追加 RRS feed

  • 質問

  • 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 に入れるというやり方はできたのですが、

    ボタンを押下すると、チェックボックスが消えてしまいます。

    どのようにやると実現できるでしょうか?


    2013年3月19日 9:53

回答

  • 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
    2013年3月21日 2:11
    モデレータ

すべての返信

  • > そのあと、ボタンを押すとチェックされているチェックボックスが判断できるような
    > ものがを作りたいのですが、うまくいきません。

    意味不明です。

    「ボタン」って何ですか? 「チェックボックスが判断」ってどういうことですか?

    掲示板の反対側にいて、掲示板に書いてあること以外は知りえない回答者に、どういう情報を提供すれば質問者さんの状況が的確に把握でき、的を得た回答がもらえるか、よく考えて情報を提供していただければと思います。

    2013年3月19日 12:29
  • GridView ではなくて ListView を使用した例ですが、以下のページのような感じでいいのかな?

    ListView に配置した CheckBox で選択
    http://surferonwww.info/BlogEngine/post/2012/03/17/Select-items-by-CheckBox-placed-in-ListView.aspx

    2013年3月20日 1:00
  • 説明不足で、申し訳ないです。

    画面上に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
    2013年3月21日 1:52
  • 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
    2013年3月21日 2:11
    モデレータ
  • 列にあるチェックボックスが消えてしまいます。

    <%@ 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さんのやり方だと、チェックボックスが灰色になってしまい、オンオフができません。





    2013年3月21日 2:43

  • trapemiyaさんのやり方だと、チェックボックスが灰色になってしまい、オンオフができません。

    と書きかましたが、できました。

    気付かないうちにEnabledが"false" になっていたようです。おさわがせしました。

    trueにして実行したところ、無事取得できました。お二方ともありがとうございました。

    2013年3月21日 3:32
  • 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/

    2013年3月21日 3:33
    モデレータ
  • > チェックボックスはテーブルの構造にないもので、動的に追加しています。

    動的に追加する必要はないはずですが、動的に追加するのであればポストバックの際も動的に追加しないと、ポストバックしたとき消えてしまいます。


    > if (((CheckBox)GridView2.Rows[i].Cells[3].Controls[1]).Checked) {
    > でエラーが起きてしまい、

    エラーが起きてしまうというだけでは情報不足です。どういうエラーが出ているか、エラーメッセージをコピペしてください。

    たぶん、CheckBox が取得できてないのだと思いますが、その場合、コードで CheckBox に ID を付与して、FindControl メソッドで探すのが確実です。

    2013年3月21日 3:44