C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: vb.netでのチェックボックスについて


(過去ログ 109 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■64924 / inTopicNo.1)  vb.netでのチェックボックスについて
  
□投稿者/ don (1回)-(2013/01/22(Tue) 17:56:43)

分類:[VB.NET/VB2005 以降] 

vb.netにてチェックボックスが2つ(CheckBox1、CheckBox2)あり、
その中チェックボックスの一つしか選択出来ないようにしたいと思っています。

ラジオボタンであればと思うかもしれませんが、チェックボックスである理由は、
ユーザーが選択(チェック)した後、無選択に戻せないからです。
(チェックボックスであれば無選択に戻せる為)

そして以下のロジックを各チェックボックスごとに作成しました。
Private Sub CheckBox1_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
Me.CheckBox2.Checked = False
End Sub
Private Sub CheckBox2_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged
Me.CheckBox1.Checked = False
End Sub

このように作成したのですが、いざ動かしてみると、
CheckBox1をクリックしチェックを入れた後、CheckBox2をクリックすると、
CheckBox1のチェックは外れましたが、CheckBox2にチェックが入りませんでした。

CheckBox1のチェックが外れている場合は、CheckBox2をクリックしチェックを入れることが出来ましたが、
CheckBox2にチェックを入れるのにCheckBox2を2回クリックしないと出来ないため、スムーズなやり方はありますでしょうか。

ちなみに、おかしいかもしれませんが、
Private Sub CheckBox1_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
Me.CheckBox2.Checked = False
If CheckBox1Checked = False Then
CheckBox1Checked = True
Else
CheckBox1Checked = False
EndIf
End Sub
を作りましたところ、
「System.StackOverflowException' のハンドルされていない例外が発生」とあり
怒られました・・・。

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


引用返信 編集キー/
■64927 / inTopicNo.2)  Re[1]: vb.netでのチェックボックスについて
□投稿者/ 魔界の仮面弁士 (123回)-(2013/01/22(Tue) 19:00:02)
2013/01/22(Tue) 19:05:15 編集(投稿者)

No64924 (don さん) に返信
> ラジオボタンであればと思うかもしれませんが、チェックボックスである理由は、
> ユーザーが選択(チェック)した後、無選択に戻せないからです。

やろうと思えばできないこともありません。

RadioButton や CheckBox では「AutoCheck プロパティを False にする」ことで、
On/Off の切り替えをすべてプログラム制御で行わせることができるためです。

使うイベントも変わってしまいますし、コーディング量も増えるので
使いどころは限られますが、一応、そういう方法もあるということで。



> CheckBox1をクリックしチェックを入れた後、CheckBox2をクリックすると、
> CheckBox1のチェックは外れましたが、CheckBox2にチェックが入りませんでした。

『ステップ実行』してみるとわかるかと思いますが、
CheckedChanged イベントが発生するのは、クリック時だけではありません。
プログラムから Checked プロパティを変更した場合にも発生します。
On に変更した時にも発生しますし、Off になるときにも発生します。


すなわち今回の場合、下記のような動作となっていたわけです。

★ 1 と 2 が Off のときに、ユーザーが 1 をクリックした。
 ・1 の AutoCheck は True のため、1 が On 状態となる。
 ・この操作により 1 の変更イベントが発生し、2 を Off にするが、
  2 はすでに Off のため、2 の変更イベントは発生しない。
 ・この結果、CheckBox1 は On、CheckBox2 は Off になる。

★ 1 が On、2 が Off のときに、ユーザーが 2 をクリックした。

 ・2 の AutoCheck は True のため、2 が On 状態となる。
 ・この操作により 2 の変更イベントが発生し、1 を Off にする。
  1 は On になっているため、1 の変更イベントが発生する。
 ・1 の変更イベントにより、2 が Off に戻される。これにより
  2 の状態が変わることになり、再度 2 の変更イベントが発生する。
 ・2 の変更イベントにより、1 を Off にするが、そもそも
  すでに 1 は Off であるため、1 の変更イベントは発生しない。
 ・この結果、CheckBox1 と CheckBox2 の両方が Off になる。



> 「System.StackOverflowException' のハンドルされていない例外が発生」とあり
> 怒られました・・・。

イベントが連鎖的に無限に発生するためです。
そのため、プログラムによる Checked プロパティ変更時は、
何かフィールド変数などでフラグ判定を行うなどして、
ユーザー操作による変更と区別するようにしてみてください。
引用返信 編集キー/
■64928 / inTopicNo.3)  Re[1]: vb.netでのチェックボックスについて
□投稿者/ Three Uncles (1回)-(2013/01/22(Tue) 19:06:05)
> そして以下のロジックを各チェックボックスごとに作成しました。
> Private Sub CheckBox1_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
> Me.CheckBox2.Checked = False
> End Sub
> Private Sub CheckBox2_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged
> Me.CheckBox1.Checked = False
> End Sub
>
> このように作成したのですが、いざ動かしてみると、
> CheckBox1をクリックしチェックを入れた後、CheckBox2をクリックすると、
> CheckBox1のチェックは外れましたが、CheckBox2にチェックが入りませんでした。

まぁ、当然でしょう。
CheckBox2にチェックを付けた時、イベントでCheckBox2_CheckedChangedが呼び出されますが、ここで

> Me.CheckBox1.Checked = False

が実行されるわけですが、この時にCheckBox1のチェック状態が変わります。
つまり、イベントでCheckBox1_CheckedChangedが呼び出されます。
ここでは、

> Me.CheckBox2.Checked = False

が実行されますので、CheckBox2のチェックは外されるわけです。

もし、自分がチェックされたら相手のチェックを外す、ということを行いたいのであれば、
こんな感じでどうでしょう(動作未確認)。

Private Sub CheckBox1_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
If Me.CheckBox1.Checked Then '念のため、CheckBox1にチェックを付けた時、この段階でCheckBox1.CheckedがTrueになっているかを確認してください。
Me.CheckBox2.Checked = False
End If
End Sub

引用返信 編集キー/
■64929 / inTopicNo.4)  Re[2]: vb.netでのチェックボックスについて
□投稿者/ don (2回)-(2013/01/22(Tue) 19:37:45)
No64927 (魔界の仮面弁士 さん) に返信

分かりやすい説明ありがとうございます。
これから、イベントの動きを順序付けて考えていきたいと思います。
ご返答の細ありがとうございました。

> 2013/01/22(Tue) 19:05:15 編集(投稿者)
>
> ■No64924 (don さん) に返信
>>ラジオボタンであればと思うかもしれませんが、チェックボックスである理由は、
>>ユーザーが選択(チェック)した後、無選択に戻せないからです。
>
> やろうと思えばできないこともありません。
>
> RadioButton や CheckBox では「AutoCheck プロパティを False にする」ことで、
> On/Off の切り替えをすべてプログラム制御で行わせることができるためです。
>
> 使うイベントも変わってしまいますし、コーディング量も増えるので
> 使いどころは限られますが、一応、そういう方法もあるということで。
>
>
>
>>CheckBox1をクリックしチェックを入れた後、CheckBox2をクリックすると、
>>CheckBox1のチェックは外れましたが、CheckBox2にチェックが入りませんでした。
>
> 『ステップ実行』してみるとわかるかと思いますが、
> CheckedChanged イベントが発生するのは、クリック時だけではありません。
> プログラムから Checked プロパティを変更した場合にも発生します。
> On に変更した時にも発生しますし、Off になるときにも発生します。
>
>
> すなわち今回の場合、下記のような動作となっていたわけです。
>
> ★ 1 と 2 が Off のときに、ユーザーが 1 をクリックした。
>  ・1 の AutoCheck は True のため、1 が On 状態となる。
>  ・この操作により 1 の変更イベントが発生し、2 を Off にするが、
>   2 はすでに Off のため、2 の変更イベントは発生しない。
>  ・この結果、CheckBox1 は On、CheckBox2 は Off になる。
>
> ★ 1 が On、2 が Off のときに、ユーザーが 2 をクリックした。
>
>  ・2 の AutoCheck は True のため、2 が On 状態となる。
>  ・この操作により 2 の変更イベントが発生し、1 を Off にする。
>   1 は On になっているため、1 の変更イベントが発生する。
>  ・1 の変更イベントにより、2 が Off に戻される。これにより
>   2 の状態が変わることになり、再度 2 の変更イベントが発生する。
>  ・2 の変更イベントにより、1 を Off にするが、そもそも
>   すでに 1 は Off であるため、1 の変更イベントは発生しない。
>  ・この結果、CheckBox1 と CheckBox2 の両方が Off になる。
>
>
>
>>「System.StackOverflowException' のハンドルされていない例外が発生」とあり
>>怒られました・・・。
>
> イベントが連鎖的に無限に発生するためです。
> そのため、プログラムによる Checked プロパティ変更時は、
> 何かフィールド変数などでフラグ判定を行うなどして、
> ユーザー操作による変更と区別するようにしてみてください。
引用返信 編集キー/
■64930 / inTopicNo.5)  Re[2]: vb.netでのチェックボックスについて
□投稿者/ don (3回)-(2013/01/22(Tue) 19:40:57)
No64928 (Three Uncles さん) に返信

ありがとうございます。
お教え下さったロジックで思い通りの実行が出来ることができました。
(ステップインで試したところ、If内にうまく入ってくれました。)
ご返答のほど、ありがとうございました。

>>そして以下のロジックを各チェックボックスごとに作成しました。
>>Private Sub CheckBox1_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
>> Me.CheckBox2.Checked = False
>>End Sub
>>Private Sub CheckBox2_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged
>> Me.CheckBox1.Checked = False
>>End Sub
>>
>>このように作成したのですが、いざ動かしてみると、
>>CheckBox1をクリックしチェックを入れた後、CheckBox2をクリックすると、
>>CheckBox1のチェックは外れましたが、CheckBox2にチェックが入りませんでした。
>
> まぁ、当然でしょう。
> CheckBox2にチェックを付けた時、イベントでCheckBox2_CheckedChangedが呼び出されますが、ここで
>
>>Me.CheckBox1.Checked = False
>
> が実行されるわけですが、この時にCheckBox1のチェック状態が変わります。
> つまり、イベントでCheckBox1_CheckedChangedが呼び出されます。
> ここでは、
>
>>Me.CheckBox2.Checked = False
>
> が実行されますので、CheckBox2のチェックは外されるわけです。
>
> もし、自分がチェックされたら相手のチェックを外す、ということを行いたいのであれば、
> こんな感じでどうでしょう(動作未確認)。
>
> Private Sub CheckBox1_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
> If Me.CheckBox1.Checked Then '念のため、CheckBox1にチェックを付けた時、この段階でCheckBox1.CheckedがTrueになっているかを確認してください。
> Me.CheckBox2.Checked = False
> End If
> End Sub
>
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -