質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

Q&A

解決済

1回答

1879閲覧

CheckBoxListに挙動をつけたい

UShow

総合スコア4

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

0グッド

0クリップ

投稿2020/12/02 10:47

前提・実現したいこと

ASP.NET C#で、チェックボックスリストに以下の挙動を付けたいです。
① CheckBoxList(Id=ch1)はDBから汲み上げた項目で、Text=(全て)、1、2、3...と続くようにしている。AutoPostBackでチェックボックスを制御。
② (全て)のチェックボックスにチェックがついた際、その他のチェックボックスを非活性かつチェックをつける
③ (全て)のチェックボックスのチェックが外れた際、その他のチェックボックスを活性かつチェックを外す
④ ③のとき、チェックボックス1、チェックボックス2、チェックボックス3、の各自にチェックがつけられるようにする。

発生している問題

現在、④を再現できなくて困っています。恐らく③の影響でチェックボックス1,2,3にチェックを入れてもAutoPosyBackでチェックが外れてしまいます。

該当のソースコード

C#

1public void chl_SelectedIndexChange(object sender, EventArgs e) 2 { 3 CheckBoxList chl = (CheckBoxList)FindControl("chl"); 4 ListItemCollection collection = chl.Items; 5 ListItem itemAll = collection.FindByText("(全て)"); 6 ListItem item1 = collection.FindByText("1"); 7 ListItem item2 = collection.FindByText("2"); 8 ListItem item3 = collection.FindByText("3"); 9 10 //判定条件1:(全て)がチェックのとき、その他ボックスは編集不可かつチェックを入れる。 11 if (itemAll.Selected == true) 12 { 13 item1.Selected = true; 14 item2.Selected = true; 15 item3.Selected = true; 16 item1.Enabled = false; 17 item2.Enabled = false; 18 item3.Enabled = false; 19 } 20 else //判定条件2:(全て)にチェックがないとき、その他ボックスは編集可能かつチェックを外す。 21 { 22 item1.Selected = false; 23 item2.Selected = false; 24 item3.Selected = false; 25 item1.Enabled = true; 26 item2.Enabled = true; 27 item3.Enabled = true; 28 } 29 //判定条件3を追加する?:item1,item2,item3にチェックを入れた際、そのチェックを保持したい(現状、判定条件2によってチェックが外れてしまう)。 30 }

試したこと

サーバーコントロールをチェックボックスリストではなくチェックボックスにした際はうまくいきましたが、SQLServerのDBから項目を汲み上げているので、何とかチェックボックスリストで再現したいです。

補足情報(FW/ツールのバージョンなど)

質問者:ASP.Net、C#ともに触れて1カ月の超初心者。
使用環境:Visual Studio2017、.NET Framework4.6.2以降

毎度拙い質問で申し訳ございません。よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/12/03 00:53

今回の条件は前のスレッドのものと少し異なりますね。見落としてました。 「その他のチェックボックス」に順次チェックを入れていって、すべての「その他のチェックボックス」にチェックが入ったときはどうするのですか? http://surferonwww.info/Test/15_Test.aspx のサンプルの動きを期待しているのではないのですか?
UShow

2020/12/04 04:38

回答が遅れ失礼いたしました。 「全て」チェックボックス以外の他ボックスがすべてチェックされたとき、②に挙動にしたいと考えています。
guest

回答1

0

ベストアンサー

④ ③のとき、チェックボックス1、チェックボックス2、チェックボックス3、の各自にチェックがつけられるようにする。

現在、④を再現できなくて困っています。恐らく③の影響でチェックボックス1,2,3にチェックを入れてもAutoPosyBackでチェックが外れてしまいます。

質問に書いてあったコードの else 文(下記)では、

else //判定条件2:(全て)にチェックがないとき、その他ボックスは編集可能かつチェックを外す。 { item1.Selected = false; item2.Selected = false; item3.Selected = false; item1.Enabled = true; item2.Enabled = true; item3.Enabled = true; }

「その他ボックス」をクリックすると AutoPoseBack でポストバックポストされ、そこに制御が飛んで無条件でチェックを外すから「チェックが外れてしまいます」となるのは当然です。

条件が足りないです。else の中でポストバックする前の「(全て) チェックボックス」にチェックがあったかどうかを調べ、チェックがあった場合のみ上の else の中のコードを実行するようにすれば期待通りになると思います。

ポストバックする前の「(全て) チェックボックス」にチェックがあったかどうかは、ViewState を利用すれば調べられます。

なお、質問のコメント欄に書いた

「その他のチェックボックス」に順次チェックを入れていって、すべての「その他のチェックボックス」にチェックが入ったとき

については、質問のコメントに返事がないので不要と判断したので、考えてません。

投稿2020/12/03 12:13

編集2020/12/04 03:52
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

UShow

2020/12/04 04:43

ご回答ありがとうございます。 >else の中でポストバックする前の「(全て) チェックボックス」にチェックがあったかどうかを調べ、チ>ェックがあった場合のみ上の else の中のコードを実行するようにすれば期待通りになると思います。 >ポストバックする前の「(全て) チェックボックス」にチェックがあったかどうかは、ViewState を利用すれば調べられます。 なるほど…。ViewStateを使えばよいのですね。 ViewStateについて全然知りませんでしたので助かりました。 ネットで「ViewStateを使ってチェックボックスにチェックがあったか判断させる」ためのコードについて調べてみます。 今週中には解決済みに出来るように頑張りますが、実際にコードを書いてみてうまくいくまで解決済みにするのはお待ちいただけたらと思います。 この度も迅速なご回答ありがとうございました。
退会済みユーザー

退会済みユーザー

2020/12/04 05:08

ViewSate にはサーバーコントロールが持っていてプログラマに意識させないで ASP.NET が自動的に使うものと、プログラマが自分でコードを書いて設定するものがありますので注意してください。 今回、使うのは後者です。 > ネットで「ViewStateを使ってチェックボックスにチェックがあったか判断させる」ためのコードについて調べてみます。 それでは多分ヒットしないと思います。 ViewState["PreviousState"] = CheckBoxList1.Items.FindByText("ALL").Selected; if ((bool)ViewState["PreviousState"]) { ... } というようなコードを自分で書くのです。
UShow

2020/12/04 05:36

コードありがとうございます!!( ;∀;) ご指摘の通りネットでなかなかヒットせず困っていました!コードとても助かります! 頂いたコードをもとに早速書いてみます。
UShow

2020/12/04 06:57

```C# public void chl_SelectedIndexChange(object sender, EventArgs e) { CheckBoxList chl = (CheckBoxList)FindControl("chl"); ListItemCollection collection = chl.Items; ListItem itemAll = collection.FindByText("(全て)"); ListItem item1 = collection.FindByText("1"); ListItem item2 = collection.FindByText("2"); ListItem item3 = collection.FindByText("3");   //ViewStateを追加    ViewState["PreviousState"] = chl.Items.FindByText("ALL").Selected; //判定条件1:(全て)がチェックのとき、その他ボックスは編集不可かつチェックを入れる。 if (itemAll.Selected == true) { item1.Selected = true; item2.Selected = true; item3.Selected = true; item1.Enabled = false; item2.Enabled = false; item3.Enabled = false; } else if((bool)ViewState["PreviousState"] == false )  //else の中でポストバックする前の「(全て) チェックボックス」にチェックがあったかどうかを調べ { //(全て)にチェックがないとき、その他ボックスは編集可能かつチェックを外す。 item1.Selected = false; item2.Selected = false; item3.Selected = false; item1.Enabled = true; item2.Enabled = true; item3.Enabled = true; } } ``` 頂いたコードをもとに書いてみたのですが、追加するべきViewStateの場所などはこれであってますでしょうか? 現在、CheckBoxAllを外した場合、他のチェックボックスが編集不可かつチェックになってしまうので、私のコードは間違えていますよね…
退会済みユーザー

退会済みユーザー

2020/12/04 07:45

違いますね。ロジックをよく考えてください。 最初の ViewState["PreviousState"] = chl.Items.FindByText("ALL").Selected; は chl_SelectedIndexChange メソッド ではなくて、Page_Load メソッドの中て初期画面表示の時(IsPostBak が fasle の時)に設定、 esle if((bool)ViewState["PreviousState"] == false ) ではなくて else の { } の中に if ((bool)ViewState["PreviousState"]) { ... } を入れて ... の部分で true / false の設定を行ってください。 さらに、chl_SelectedIndexChange メソッドの最後で ViewState["PreviousState"] = itemAll.Selected; とするのを忘れずに。
退会済みユーザー

退会済みユーザー

2020/12/04 07:46

回答にも書きましたが、質問のコメント欄に書いた >「その他のチェックボックス」に順次チェックを入れていって、すべての「その他のチェックボックス」にチェックが入ったとき については、返事がないので不要と判断し、考えてません。
UShow

2020/12/04 08:50

ご返信ありがとうございます! IsPostBackがfalseの場合ということは、ポストバックでない最初のページ要求の時にViewStateを設定すればよいのですね コードは ```C# public void Page_Load(object sender, EventArgs e) { if (!IsPostBack) {    //チェックボックスを取得(不要?)    CheckBoxList chl = (CheckBoxList)FindControl("chl");    ListItemCollection collection = chl.Items;    ListItem itemAll = collection.FindByText("(全て)");        //ViewStateに独自の値を保存する    ViewState["PreviousState"] = chl.Items.FindByText("ALL").Selected;    }   } ``` で恐らく合っていると思ったのですが、この場合 「オブジェクト参照がオブジェクト インスタンスに設定されていません。」とエラーが出てしまいます… //判定条件1:(全て)がチェックのとき、その他ボックスは編集不可かつチェックを入れる。 if (itemAll.Selected == true) { item1.Selected = true; item2.Selected = true; item3.Selected = true; item1.Enabled = false; item2.Enabled = false; item3.Enabled = false; } else {  if ((bool)ViewState["PreviousState"])  {   //true / false の設定を行う  } } ここでいうtrue / false の設定とは、 (bool)ViewState["PreviousState"] == trueのとき //ポストバックする前の「(全て) チェックボックス」にチェックがあったときその他ボックスは編集可能かつチェックを外す。 { item1.Selected = false; item2.Selected = false; item3.Selected = false; item1.Enabled = true; item2.Enabled = true; item3.Enabled = true; } (bool)ViewState["PreviousState"] == falseのとき //ポストバックする前の「(全て) チェックボックス」にチェックがなかったとき、編集可能の普通のチェックボックスの挙動 ということでしょうか? ViewStateが初めての概念なのでかなり混乱した文章になり申し訳ございません…。 >「その他のチェックボックス」に順次チェックを入れていって、すべての「その他のチェックボックス」にチェックが入ったとき ↑のときについては②の挙動にしたいと考えております。
UShow

2020/12/04 08:54

回答者様にする質問ではないと存じますが、 public void Page_Load(object sender, EventArgs e)のif (!IsPostBack)でViewStateが定義できない(「オブジェクト参照がオブジェクト インスタンスに設定されていません。」エラー)問題はまた別にスレッドを建てたほうがよろしいでしょうか。 少し調べてみて自己解決できなさそうならスレッドを建てること、検討しようと思っております。
退会済みユーザー

退会済みユーザー

2020/12/04 09:10

普通にやっていればそんなことは起こり得ないことで、私の想像の斜め上のことをやっているとしか思えません。 質問者さん、あまりに勉強不足と思います。
UShow

2020/12/04 09:16

失礼いたしました。 精進します。
退会済みユーザー

退会済みユーザー

2020/12/05 01:11 編集

ASP.NET Web Forms アプリの教本を買ってきて、その本にあるサンプルコードを自分で書いて動かしながら最初から最後まで読んで、体系的な知識を付けることをお勧めします。 一から十まで手取り足取り教えてもらってプログラミングするというのは、研修などで講師と Face-to-Face でやり取りできる環境でないと無理です。Teratail のようなネットを通じて文章でのやり取りする Q&A サイトではそれは期待しすぎです。 (一を聞いて十を知るまでは無理でも、本を読むなどして体系的に勉強すれば、一を聞いたら八ぐらいまで知ることができるようになるのではと思います)
退会済みユーザー

退会済みユーザー

2020/12/07 04:46

以前のスレッド https://teratail.com/questions/305808 の話を忘れていました。 前の質問者さんのスレッドの話と同様に、SQL server のテーブルから SqlDataSource を利用してデータを取得し、それを CheckBoxList の DataSourceID に設定したということですか? そうであれば、SQL Server のデータが CheckBoxList にバインドされるのは Page.Load イベントより後になるので、Page_Load では「オブジェクト参照がオブジェクト インスタンスに設定されていません。」という結果になったのでしょう。 CheckBoxList の項目をデータバインドするのであれば、CheckBoxList.DataBound イベントのハンドラで ViewState["PreviousState"] を設定してください。
UShow

2020/12/07 08:56

回答者様 ご丁寧なご回答、誠にありがとうございます。 こちらの記載漏れにも関わらず以前の私のスレッドから原因の推測をして頂いたり、体系的な知識の不足をご指摘頂いたり、本当にお世話になっております。 ご指摘の通り、今回のCheckBoxListはSQL ServerのDBとバインドしています。 ご回答いただいたとおりに、改めてCheckBoxList.DataBound イベントのハンドラにてViewState["PreviousState"] を定義してみます。 動きましたら無論ご報告させていただきますので、「解決済み」はもう少しお待ちいただければ幸いです。
UShow

2020/12/08 05:57

この度はありがとうございました。 頂いたご回答通りにしたところ、無事に動きましたので解決済みにさせていただきます。 基礎的な拙い質問など、大変お手数おかけしました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問