DOBON.NET DOBON.NETプログラミング掲示板過去ログ

RadioButtonとListView

分類:[.NET]

VB.netを始めたばかりで、非常に初歩的な質問なのですが、
よろしくお願いします。

RadioButtonでチェックした内容に基づいて、ListViewの
項目を選択させたいのですが、うまくいきません。

このような使い方はできないのでしょうか?

'コード
Private Sub RadioButton1_CheckedChanged(ByVal sender ...)
ListView1.Items(1).Checked = True
End Sub

'エラー
'System.ArgumentOutOfRangeException' のハンドルされていない例外が system.windows.forms.dll で発生しました。

追加情報 : 指定された引数は、有効な値の範囲内にありません。
  • 題名: Re[1]: RadioButtonとListView
  • 著者: 北北
  • 日時: 2004/01/29 10:29:51
  • ID: 2289
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
ListView使ったことが無いので適当なこと言えませんが、、、

> 追加情報 : 指定された引数は、有効な値の範囲内にありません。

↑このエラーから、ListViewに追加したアイテムの数が1個以下なんではないでしょうか?
僕も初心者なんで間違っていたらすみません。。。
■No2285に返信(n.kさんの記事)

> Private Sub RadioButton1_CheckedChanged(ByVal sender ...)
> ListView1.Items(1).Checked = True

ListView1.Items(1).Selected = True

簡単な答えで申し訳ないですが、これで出来るようです。
お返事遅くなってすみません。

>>Private Sub RadioButton1_CheckedChanged(ByVal sender ...)
>> ListView1.Items(1).Checked = True
>
> ListView1.Items(1).Selected = True
>
> 簡単な答えで申し訳ないですが、これで出来るようです。
チェックボックスを表示していますので、記述に間違いはないと
思うのですが、いずれにしても、
Form1_Load時であればエラーは表示されないようです。
(アドバイスいただいた記述でも、Form1_Load時でなければ
同じエラーになります)

RadioButton1_CheckedChanged時に、チェックする方法は
ないのでしょうか?
n.kさん、こんばんは。深山と申します。

 私も試してみましたけど、特に問題ありませんでした。特定のイベントに関連付けられた
関数内でのみ上手くいかないということはないと思うのですが‥‥。

 少し気になったのは例として
> ListView1.Items(1).Checked = True
と記述されていること。 Items のインデックスは 0 から始まりますから、この内容ですと
上から二つ目の項目にチェックを付けようとしてることになります。これは意図した
動作なのでしょうか?
 もしそうでなく、リストに項目が一つしかなければ
> 追加情報 : 指定された引数は、有効な値の範囲内にありません。
というエラーが発生したのも納得なのですけれども。

 そうでないなら Checked プロパティの値を変更する前に ListView ないし Items を
Clear してしまってるとか‥‥他にも原因は考えられるかも知れませんが、想像の域は出ません。
 該当部分のコードを全て投稿されては如何でしょう?
# 最初に投稿されたのが全文でしたら私にはお手上げです(^_^;)
深山さん、ありがとうございます。

下記が該当部分のコードです。

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ListView1.Items.Add("test01")
ListView1.Items.Add("test02")
ListView1.Items(0).SubItems.Add("正常")
ListView1.Items(1).SubItems.Add("失敗")
'ListView1.Items(1).Checked = True
'ListView1.Items(0).Checked = True
End Sub

Private Sub RadioButton1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton1.CheckedChanged
ListView1.Items(0).Checked = True
End Sub

>  少し気になったのは例として
>>ListView1.Items(1).Checked = True
> と記述されていること。 Items のインデックスは 0 から始まりますから、この内容ですと
> 上から二つ目の項目にチェックを付けようとしてることになります。これは意図した
> 動作なのでしょうか?
はい、意図したものです。ちなみに、0にしても結果は同じでした。
よろしくお願いします。
こんにちは、n.kさん。ピラルクです。

デザイン画面でCheckedしていると、Form_Loadより先に
RadioButton1_CheckedChangedイベントが走るみたいです。
(Visual開発ってそんな仕様だったかなぁ...(?_?))

対策方法1:
 デザイン時には全てChecked=Falseにし、
 Eventが走ってもOKになってから(この場合Form1_Loadの末尾)、
 Radioの初期選択を設定する。

対策方法2:
イベントの入り口で判定を入れる。
Private Sub RadioButton1_CheckedChanged(...
'初期化中はEventを実行しない
If Not Me.Visible Then Exit Sub

……
End Sub

対策方法その他:
 自分で都合の良い段階でEventHandlerを書くとかも可能。
> デザイン画面でCheckedしていると、Form_Loadより先に
> RadioButton1_CheckedChangedイベントが走るみたいです。
> (Visual開発ってそんな仕様だったかなぁ...(?_?))
 あぁ、そうか!
 すいません。最近 C# ばかり触ってたので失念してました。
# 実験したときも VB ではなく C# だったり‥‥相手の方と同じ環境でやらなければ意味ない
# ですよね(汗) 申し訳ありませんm(__)m >n.kさん

> Private Sub RadioButton1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton1.CheckedChanged
のように Handles を用いて静的にイベントを作成している場合、フォームのインスタンスが
生成された時点でイベントが有効になるようです。
 デザイン画面で行うプロパティの設定も、自動生成されたコード内に記述されます。実行時に
プロパティの値を変更することに変わりありませんから、このケースのようなことも起こると。
# 一部適切ではない表現になってるかも知れませんけど、気にしないで下さいませ(^_^;)

 対策はピラルクさんが仰られているので必要ありませんね。

> > 上から二つ目の項目にチェックを付けようとしてることになります。これは意図した
> > 動作なのでしょうか?
> はい、意図したものです。ちなみに、0にしても結果は同じでした。
 あはは、余計なお世話でしたね(^_^;)
 では余計なことを言ってしまったついでにもう一つ。もしご存知なかったら、なのですけども。
 ピラルクさんが仰られた『対策方法その他』についても、どうすれば実現できるのかご検討
されるとよろしいですよ。今回は必要ないとしても色々な手段を知ってることはどこかで
活きてきますから。
 ‥‥って、なんか偉そうに聞こえたらごめんなさい(汗)
ピラルクさん、深山さんありがとうございました。

>>デザイン画面でCheckedしていると、Form_Loadより先に
>>RadioButton1_CheckedChangedイベントが走るみたいです。
たしかに、デザイン画面でCheckedしていました。

>  では余計なことを言ってしまったついでにもう一つ。もしご存知なかったら、なのですけども。
>  ピラルクさんが仰られた『対策方法その他』についても、どうすれば実現できるのかご検討
> されるとよろしいですよ。今回は必要ないとしても色々な手段を知ってることはどこかで
> 活きてきますから。
現時点では、EventHandlerを書くということは、想像できませんが、
機会があれば挑戦してみたいと思います。
  • 題名: Re[8]: RadioButtonとListView
  • 著者: Codingslave
  • 日時: 2004/02/12 10:08:09
  • ID: 2464
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
> デザイン画面でCheckedしていると、Form_Loadより先に
> RadioButton1_CheckedChangedイベントが走るみたいです。
> (Visual開発ってそんな仕様だったかなぁ...(?_?))
Visual BasicではNewでオブジェクトが作られた時点でイベントハンドラが結び付けられます。そのため、デザイナの内容を反映するためのInitializeComponent()内のMe.RadioButton1.Checked = Trueの部分でCheckedChangedが呼び出されてしまいます。

RadioButtonのTagプロパティを使用していないならば、関連付けられたListViewItemをTagに格納しておいて、Loadが行われたか否かをTagプロパティで判断するというのはどうでしょう。

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim item1 As ListViewItem = New ListViewItem("test01")
item1.SubItems.Add("正常")
RadioButton1.Tag = item1
ListView1.Items.Add(item1)

Dim item2 As ListViewItem = New ListViewItem("test02")
item2.SubItems.Add("失敗")
RadioButton2.Tag = item2
ListView1.Items.Add(item2)
End Sub

Private Sub RadioButton1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton1.CheckedChanged, RadioButton2.CheckedChanged
Dim radioButton As RadioButton = sender
Dim item As ListViewItem = radioButton.Tag

If Not item Is Nothing Then
item.Checked = radioButton.Checked
End If
End Sub
  • 題名: Re[6]: RadioButtonとListView
  • 著者: ピラルク
  • 日時: 2004/02/14 13:53:38
  • ID: 2511
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
こんにちは。ピラルクです。

> デザイン画面でCheckedしていると、Form_Loadより先に
> RadioButton1_CheckedChangedイベントが走るみたいです。
> (Visual開発ってそんな仕様だったかなぁ...(?_?))

VB6以前で以下のようなコードを実行させると、

Private Sub Form_Initialize()
Debug.Print "Begin-Form_Initialize"
Option1.Value = True
Debug.Print "End---Form_Initialize"
End Sub

Private Sub Form_Load()
Debug.Print "Run---Form_Load"
End Sub

Private Sub Option1_Click()
Debug.Print "Run---Option1_Click"
End Sub

その結果は、

Begin-Form_Initialize
Run---Form_Load
Run---Option1_Click
End---Form_Initialize

と (Me.)Option1にアクセスした瞬間、Form_Loadが先に処理
されていました。だから「Form_Loadイベントは初期化処理を
書くところ」という慣れがあるのですが、.NETではそれは間
違いということですね。

> 対策方法2:
> イベントの入り口で判定を入れる。
> Private Sub RadioButton1_CheckedChanged(...
> '初期化中はEventを実行しない
> If Not Me.Visible Then Exit Sub
>
> ……
> End Sub

上記のように書くよりは、

Private Sub RadioButton1_Click(...
……
End Sub

と、VB6と同じようにClickイベントを使うほうが適切でした。(訂正)

しかし、以下サイト
▼Visual Basic .NET における OptionButton コントロールの変更点
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vbcon/html/vxconchangestooptionbuttoncontrolinvisualbasicnet.asp
によると、VB6のOptionButtonのClickイベントに対応するのは
CheckedChangedだという。文頭のVB6コードを自動変換し実行
結果を見ると、

Begin-Form_Initialize
Run---Option1_Click (<---CheckedChangedに変っている)
End---Form_Initialize
Run---Form_Load

でした。Form_LoadイベントはMeのアクセスに先立って実行
されるというVB6ルールは、自動変換では要注意ですね。
.NETではモデルとビューを区別して見る視点が必要という
ことでしょうか。

DOBON.NET | プログラミング道 | プログラミング掲示板