- PR -

【ASP.NET】DataGridのテンプレート列に入れたCheckBoxのイベントの挙動がおかしい

1
投稿者投稿内容
ひで
会議室デビュー日: 2003/05/13
投稿数: 1
投稿日時: 2005-02-13 23:44
お世話になります。

C#でWebアプリの開発を行っています。
DataGridにテンプレート列を作り、そこにCheckBoxを設定しています。

まず、使用方法を先に説明してしまいますと、DataGridはSQLServerのあるテーブルとバインドしているのですが、CheckBoxに対応している列でチェックが入る(つまり値がtrueな)のは必ず1行だけです。
チェックが入っていないCheckBoxがクリックされるとDBにデータが反映されると同時に、他の行にあったチェックが外されます。
そこで、CheckBoxのAutoPostBackをTrueにし、CheckedChangedイベントのハンドラを設定しているのですが、うまくイベントが拾えません。
具体的には、ある行にチェックがついていると、それより下にチェックを付けても、なぜかCheckedChangedイベントのハンドラで取得できるのは以前にチェックが付いていた行なのです。
しかし、それより上にチェックをつけるとうまく動作します。

また、チェックを外したときはイベント自体が発生しません。
チェックが外れるのは「ある行がチェックされたから以前チェックが付いていた行は結果的にチェックが外される」というのに限られ、既にチェックが付いているCheckBoxをクリックしても無視するようにコードでは記述しています。
しかし、イベント自体が発生しないので、画面上はチェックが外れたように表示されています。
具体的なコードは抜粋ですが以下の通りです。
ちなみに、どのチェックボックスがクリックされたかはCheckBoxのTextプロパティで判断しています。

private void checkBox_CheckedChanged(object sender, System.EventArgs e)
{
CheckBox checkBox = (CheckBox)sender;

if(checkBox.Checked == false)
{
// チェックが入っているものをクリックしてチェックを外すことは出来ない。
checkBox.Checked = true;
}
else
{
DBに対する処理をするメソッドの実行;
}
DataGridを再描画するメソッドの実行;
}

private void partyList_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
// CheckBox にイベントハンドラの設定
CheckBox checkBox;

checkBox = (CheckBox)e.Item.Cells[3].Controls[1];
checkBox.CheckedChanged += new System.EventHandler(this.checkBox_CheckedChanged);
}

以上、よろしくお願いいたします。

PS.
ボタンみたいにもっと簡単にDataGrid内のイベントが取れると良いのですが...
SE卵
大ベテラン
会議室デビュー日: 2004/10/22
投稿数: 135
投稿日時: 2005-02-14 11:13
こんにちは。
最初に言っておきますが、あくまで私のやり方なので、他にも良い
やり方はあるかもしれません。

@ まず、HTML上で、OnCheckedChangedを設定します。
コード:
<asp:TemplateColumn>
    <ItemTemplate>						
        <asp:CheckBox id=chkBox runat="server" OnCheckedChanged="checkBox_CheckedChanged" AutoPostBack="true" Checked='<%# DataBinder.Eval(Container, "DataItem.Data") %>'>
        </asp:CheckBox>
    </ItemTemplate>
</asp:TemplateColumn>



A次に以下メソッドを追加
コード:
public void checkBox_CheckedChanged(object sender, System.EventArgs e){
  '' 処理内容
}



これでどうでしょう?VBで確認しましたが、正常に動きました。
もし駄目でしたら、すいません。

あと、checkBox_CheckedChangedメソッドをpublicで宣言してくださいね。
privateだと駄目みたいなんで。。。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-02-14 20:28
> checkBox = (CheckBox)e.Item.Cells[3].Controls[1];
 ほとんどのポストでこうなっているんだけれど、セル位置はともかく、コントロール配列までマジックナンバーでいいのだろうか?


 それはともかく。
> うまくイベントが拾えません。
 これは、「サーバ側にポストされているが、イベントハンドラがコールされない」のでしょうか。それとも、「サーバへポストされない」のでしょうか。
 前者の場合、ViewStateをTrueにすると、いいかもしれません。またソースを確認して、すべてのチェックボックスにAutoPostBackのためのスクリプトが記述されているか確認してみましょう。それから、ポストバックでDataBindするとイベントは発生しません。データソースの設定と、バインドが適切な場所でされているかチェックしましょう。


 「チェックされるのは1つ」は、クライアント側でやるほうが、ユーザビリティは向上しますね。もちろん、サーバ側でも複数チェックされていないか確認する必要があります。

_________________
ジョン吉
常連さん
会議室デビュー日: 2005/02/25
投稿数: 33
投稿日時: 2005-02-28 15:25
このスレッド古い日付ですが、DataGrid + CheckBox でヒットして、
結構目につくので、メモ代わりに情報を付け足しておきます。
既にご存じの方にはご容赦ください。

SE卵さんの方法で、テンプレート列に入れたcheckbox のイベントを発生させた時の
その行の情報の取得方法です。

ctype(sender,checkbox) →  イベントが発生したチェックボックスそのもの
ctype(ctype(sender,checkbox).BindingContainer,DataGridItem) → そのチェックボックスが設置されている行

ということは、チェックボックスのOn/Offで色替えしたいのであれば、
dim ck as chekbox = ctype(sender,checkbox)
dim rw as GridDataItem =ctype(ck.BindingContainer,DataGridItem)

rw.backcolor=color.red

ジョン吉
常連さん
会議室デビュー日: 2005/02/25
投稿数: 33
投稿日時: 2005-02-28 15:33
書込の途中で投稿してしまいました m(__)m

行そのものが取得できるので、
rw.ItemIndex で何行目(0始まり)のデータかがわかる
rw.Cells(???) で???列のCellにアクセスできる

ということになります。

1

スキルアップ/キャリアアップ(JOB@IT)