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

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

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

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

6回答

8969閲覧

C# チェックボックスの全選択 全解除

AMK

総合スコア765

C#

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

0クリップ

投稿2021/08/26 14:50

編集2021/08/27 13:41

.NET Framework4.7.2
WPF

お世話になります。
チェックボックスの全選択・全解除をしたくいろいろと調べてここまでコードを書いたのですが
どうしても解らないので質問させていただきます。

試したことは、
checkBox1_CheckStateChanged
checkBox1_CheckedChanged
各イベントで下記のコード(マウスclickイベント以外)を入れてみたのですがチェックがついたり消えたりして
暴走してしまい希望の結果にはならなかったです。

C#

1private void checkBox1_MouseClick(object sender, MouseEventArgs e) 2 { 3 if (checkBox1.Checked == true) 4 { 5 6 foreach (Control item in groupBox2.Controls) 7 { 8 if (item.GetType().Equals(typeof(CheckBox))) 9 { 10 ((CheckBox)item).Checked = false; 11 } 12 } 13 14 15 } 16 else 17 { 18 foreach (Control item in groupBox2.Controls) 19 { 20 if (item.GetType().Equals(typeof(CheckBox))) 21 { 22 ((CheckBox)item).Checked = true; 23 } 24 } 25 } 26 }

チェックボックスは下記のような仕様になっています
イメージ説明

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/08/26 15:12

・プロジェクトの種類(Windowsフォームアプリ、WPFアプリ、ASP.NET Webアプリ等) ・フレームワークのバージョン(.NET Framework X.X、.NET Core X.X等) を質問を編集して追記してください。
YT0014

2021/08/27 01:17

checkBox1とgroupBox2の関係をご提示ください。 checkBox1は、groupBox2に含まれているチェックボックスですか?
退会済みユーザー

退会済みユーザー

2021/08/27 06:00

質問者さん、無言ですが、いくつか回答がでているのでそれらに対するフィードバックを書きましょう。役に立った/立たなかったぐらいはすぐ返せるはず。役に立たなかったなら、どこがダメだったかを書くと、より質問者さんが期待する答えに近いものが出てくるかも。とにかく無言で放置は NG です。
AMK

2021/08/27 13:36 編集

スミマセン、今帰宅しました checkbox1は、グループ2内に存在します。
guest

回答6

0

SurferOnWwwさんと同じような前提条件の元、CheckedChangedを使用してます。
必要に応じてCheckedChangedイベントの削除を行って連動がスムーズになるようにしてます

親チェックボックス
CheckedChangedイベントをcheckBoxParent_CheckedChangedに紐づけ

子チェックボックス
各CheckedChangedイベントを全てcheckBoxChild_CheckedChangedに紐づけ

C#

1 private void checkBoxParent_CheckedChanged(object sender, EventArgs e) { 2 3 foreach (var obj in panel1.Controls.OfType<CheckBox>()) { 4 // 子のイベントを削除した状態で親の状態を反映 5 obj.CheckedChanged -= checkBoxChild_CheckedChanged; 6 obj.Checked = checkBoxParent.Checked; 7 obj.CheckedChanged += checkBoxChild_CheckedChanged; 8 } 9 10 } 11 12 private void checkBoxChild_CheckedChanged(object sender, EventArgs e) { 13 14 // 対象の子チェックボックスのリスト 15 var items = panel1.Controls.OfType<CheckBox>().ToList(); 16 // 子チェックボックスでチェックのついてる数 17 var checkedCount = items.Count(x => x.Checked); 18 19 // 親のイベントを削除した状態で子の状態を反映 20 checkBoxParent.CheckedChanged -= checkBoxParent_CheckedChanged; 21 22 if (checkedCount == 0) { 23 checkBoxParent.CheckState = CheckState.Unchecked; 24 } else if (checkedCount == items.Count) { 25 checkBoxParent.CheckState = CheckState.Checked; 26 } else { 27 checkBoxParent.CheckState = CheckState.Indeterminate; 28 } 29 30 checkBoxParent.CheckedChanged += checkBoxParent_CheckedChanged; 31 }

投稿2021/08/27 04:51

編集2021/08/27 04:55
dekaaki

総合スコア292

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

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

0

ベストアンサー

多分、Windows Forms アプリで、groupBox2 の中に ChechBox が複数配置されていて、それら全部の Checked プロパティを checkBox1 をマウスでクリックするごとに true/false を一度に切り替えたいのであろうと想像してレスします。

もし違ったらどう違うのか書いてください。あと、回答者・閲覧者が余計な想像をしないで済むよう、そういうことは最初から質問に書くようにしてください。

checkBox1 はどこにあるのですか?

groupBox2 の中にあるとすると、質問に書いてあったコードでは checkBox1 をクリックするたびに、checkBox1 を含めて groupBox2 の中のすべての CheckBox の Checked が書き換えられてしまうということは分かりますか? それは期待する動きではないですよね。

試しに以下のようにしてみてください。

イメージ説明

さらに、質問のコードを以下のように書き換えてください(コメントの部分)。それで checkBox1 にチェックが入ると groupBox2 内の ChechBox は全選択に、checkBox1 のチェックが外れると全解除になるはず。

C#

1private void checkBox1_MouseClick(object sender, MouseEventArgs e) 2{ 3 if (checkBox1.Checked == true) 4 { 5 foreach (Control item in groupBox2.Controls) 6 { 7 if (item.GetType().Equals(typeof(CheckBox))) 8 { 9 //((CheckBox)item).Checked = false; 10 ((CheckBox)item).Checked = true; 11 } 12 } 13 } 14 else 15 { 16 foreach (Control item in groupBox2.Controls) 17 { 18 if (item.GetType().Equals(typeof(CheckBox))) 19 { 20 //((CheckBox)item).Checked = true; 21 ((CheckBox)item).Checked = false; 22 } 23 } 24 } 25}

これが質問者さんのやりたいことそのものズバリではなくても、応用すればできるのでは?

投稿2021/08/27 01:27

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

dekaaki

2021/08/27 04:52

その方法ではスペースキーでチェック状態を変更したときに正しく動作しないのでは? 一応、SurferOnWwwさんと同じような前提条件でCheckedChangedを使用する回答を投稿しました
退会済みユーザー

退会済みユーザー

2021/08/27 05:57

MouseClick イベントは質問者さんのコードそのままです。回答に「・・・checkBox1 をマウスでクリックするごとに true/false を一度に切り替えたい・・・」「もし違ったらどう違うのか書いてください」と書いた通り、違ったら質問者さんがその旨言ってくることに期待。
fana

2021/08/27 06:05

質問の文章が難読ですが,私は 「checkBox1_CheckedChangedとかで試したら暴走した →(だから今は暴走をさけるために)クリックのイベントに書いている」 ということを言っているのかな,と読みました.
dekaaki

2021/08/27 06:28

SurferOnWwwさん。確かに質問者のソースを見るとMouseClickになってますね。 私の方こそ質問者のソースをよく見てなかったようですね。失礼しました。
Zuishin

2021/08/27 06:32

MouseClick なら質問のコードでも特に問題にならないんじゃないかと。
退会済みユーザー

退会済みユーザー

2021/08/27 06:37 編集

> 「checkBox1_CheckedChangedとかで試したら暴走した →(だから今は暴走をさけるために)クリックのイベントに書いている」ということを言っているのかな,と読みました. そうかもしれませんね。でも、ひどく情報不足の質問ですのでそのあたりは自分は深く考えず、質問者さんのコードをほとんど変えずに絶対「暴走」しないやり方を回答した次第です。
退会済みユーザー

退会済みユーザー

2021/08/27 06:39 編集

> MouseClick なら質問のコードでも特に問題にならないんじゃないかと。 checkBox1 も gruopBox2 の中に入れて、質問者さんのコードをそのままコピペしてやってみたんですが「暴走」はしないまでも動きが期待したものにならないかと思います。
AMK

2021/08/27 13:49

期待通りの動作が得られました!! ありがとうございます!!
guest

0

foreach (Control item in groupBox2.Controls)

で、checkbox1が操作されてしまい、そのイベントによりまた操作されて、、というループに陥ってませんか

投稿2021/08/26 15:45

y_waiwai

総合スコア87749

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

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

0

多分ですけど、無限ループ状態になっている気がします。

たとえばcheckbox1 ~ 3 があるとして、

checkbox1 がチェックされたら checkbox2,3 はそれぞれfalseになる。
でも checkbox2 も 「チェックされたら自分以外はfalseになる」ので、
本来ならtrueになっているはずの checkbox1 も falseになる。
でも checkbox1 が falseならそれ以外は trueになるはずだから……

のようになっているのではないかと思います。

もし、「性別」とか「年号」、「学年」...とかみたいに排他的(一つがtrueならそれ以外はfalseとか)になる関係であれば、CheckBoxではなく、「RadioButton」を使うべきです。
そっちの方が安全ですし。

どうしてもCheckBoxで表現したいなら、「フィールドとして何らかのデータを持つ」かなぁと。

イベントやその設定方法(Form1_Loadイベントに書くのかForm1のコンストラクタ内で書くのかとか) でイベントが想定しないような状態で発火することがあります。

C#だとイベント設定はForm1_Loadイベントとかでも設定できるので問題なさそうですが、言語やライブラリによっては初期設定としての設定をすると「CheckBoxの値が変わった」とかのようなイベントが発火する事があります。
(しかも本来は発火させたくない)

その場合は、

// Form1_Loadイベント内とかで CheckBox checkBox1 = new CheckBox(); checkbox1.Location = ... ... // private bool isAllowedToRunCheckedChanged がフィールドとしてあるとする isAllowedToRunCheckedChanged = true;

とかのようにして、

// CheckedChangedイベント内で if( isAllowedToRunCheckedChanged && checkbox1.Checked ){ // ここでそれ以外のCheckBoxをfalseにする isAllowedToRunCheckedChanged = false; }

のようにするとか。

若しくは、CheckBox1 だけCheckedChanged イベントを受け付けて、それ以外はスルーするとか。

とにかく、そういう風に無限ループを避けるようなロジックにすると思います。

投稿2021/08/27 02:19

BeatStar

総合スコア4958

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

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

0

groupBox2 内に配されているcheckbox群のうちの1つ以上のcheckboxに
チェック状態の変化時に走るイベントハンドラが設定されており,
且つ,そのイベントハンドラ内で checkBox1 のチェック状態を操作している

……といったことになっていませんか?

そんなことになっているとしたら,

checkbox1の操作がトリガとなって groupBox2 内のcheckbox群のチェック状態を変えるけども,
その「チェック状態を変える」がトリガとなって,前記イベントハンドラが実行されて checkBox1 のチェック状態を変化させる

という話になります.
で,このとき checkbox1 に

checkBox1_CheckStateChanged
checkBox1_CheckedChanged

みたいなのがあったりすると,「checkBox1 のチェック状態を変化させる」がトリガとなってこれらが実行されて…

という嫌な連鎖になるでしょう.

投稿2021/08/27 02:01

編集2021/08/27 02:02
fana

総合スコア11654

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

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

fana

2021/08/27 02:04

で,連鎖を断ち切るために, checkBox1_CheckedChanged とかを使うのをやめて,代替として checkBox1_MouseClick を用いてみている,という状況なのかな? と想像.
AMK

2021/08/27 13:42

その通りです^^
guest

0

試したことは、

checkBox1_CheckStateChanged
checkBox1_CheckedChanged
各イベントで下記のコード(マウスclickイベント以外)を入れてみたのですがチェックがついたり消えたりして
暴走してしまい希望の結果にはならなかったです。

何となく複数個所にイベントを設定することで、必要以上にイベントが発生しているような気がします。CheckedChangedイベントだけに設定してみては?
あと、CheckedChangedイベントでDebug.WriteLineでログを取ったりしてイベントの発生する回数を確認したり、イベントにブレークポイントを設定してスタックトレースを確認したりしてみてください。

あと、毎回Controlsを検索してTypeの比較するの非効率なので、素直にList<CheckBox>のようなメンバ変数作成して、Loadイベント辺りで操作するCheckBoxを格納すればよいのではないかと。

投稿2021/08/26 15:15

編集2021/08/27 01:50
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問