- PR -

ListBoxでのSelectedIndexChangedイベントの動作について

投稿者投稿内容
だんじり
大ベテラン
会議室デビュー日: 2007/08/10
投稿数: 155
お住まい・勤務地: 神奈川県
投稿日時: 2007-10-31 15:01
Visual Basic 2005 Express Edition でWindowsアプリケーションを開発しています。
ListBoxでのSelectedIndexChangedイベントで SS=ListBox1.SelectedValue.ToString
として選択したアイテムをSS(String)で受け取ってその後の処理をしています。
このスフトは、実行すると正常に動作していますが、このフォームを閉じると
SelectedValue部に次のようなエラーが発生します。
「オブジェクト参照がオブジェクトインスタンスを設定されていません」

NN=CInt(ListBox1.SelectedIndex)で受取るとエラーはなくなりますが元ファイルに
アクセスしてアイテムを求める面倒さがあります。こんな問題を抱えてここ2日間
悩んでいました。

ところがあるときSelectedIndexの取得数値を確認するために次のようなコードを入れました。
MessageBox.Show("Index:" & ListBox1.SelectedIndex & " Value:" & _
ListBox1.SelectedValue)
するとこのフォームを閉じたときにもSelectedIndexChangedイベントが発生していて
なんと次のような表示がされていました。
Index:-1
Value: ←DBNull
このことでエラーの問題はIsDBNullでExit Subとして解決しました。

質問したいのは、SelectedIndexChangedイベントでフォームを閉じる時にイベントが
発生するのは正常でしょうか。またなぜイベントが発生するのでしょうか。
よろしくご指導下さい。




[ メッセージ編集済み 編集者: だんじり 編集日時 2007-10-31 15:02 ]

[ メッセージ編集済み 編集者: だんじり 編集日時 2007-10-31 15:04 ]
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2007-10-31 15:30
引用:

ListBoxでのSelectedIndexChangedイベントで SS=ListBox1.SelectedValue.ToString
SelectedValue部に次のようなエラーが発生します。
「オブジェクト参照がオブジェクトインスタンスを設定されていません」

NN=CInt(ListBox1.SelectedIndex)で受取るとエラーはなくなりますが



SelectedIndexは数値であり、必ずIntegerの範囲内の値をとり、そのすべてに意味があります。
つまり基本的に例外はありえません。
そういう意味ではSelectedValueがNothingになるのは意味があることで、それ自体が例外でも何でもありません。
例外になったのは、Nothingに対して操作をおこなったからです。
まずはNothingになった理由を突き止めること、そしてその理由に対する対策をとることです。

引用:

質問したいのは、SelectedIndexChangedイベントでフォームを閉じる時にイベントが
発生するのは正常でしょうか。またなぜイベントが発生するのでしょうか。



そのフォームがMessageBoxを指すのなら、その2つに一切関連性はありません。
なぜならフォーカスによって選択されたアイテムに何の変化も起こらないからです。
変化が起こるならそのようなコードが書かれているからに他なりません。

ちなみに、SelectedValueを使用しているということはValueMemberプロパティを使用しているということでしょうか?
そうでないならSelectedItemのほうを使うとよいでしょう。
今回の書かれた現象としてはなんら変わりありませんけど。

[ メッセージ編集済み 編集者: まどか 編集日時 2007-10-31 15:33 ]
だんじり
大ベテラン
会議室デビュー日: 2007/08/10
投稿数: 155
お住まい・勤務地: 神奈川県
投稿日時: 2007-10-31 16:07
まどかさん,早速の解答ありがとうございます。
引用:

まどかさんの書き込み (2007-10-31 15:30) より:
まずはNothingになった理由を突き止めること、そしてその理由に対する対策をとることです。


「Nothingになった理由」は何も選択していない状態でイベントが発生すると
Index:-1
Value:Nothing
になるようですが、フォームを閉じるときにSelectedIndexChangedイベントがなぜ
発生するのでしょうか。ご指摘されていることは、通常発生しないということでしょうか。


引用:

そのフォームがMessageBoxを指すのなら、その2つに一切関連性はありません。


MessageBoxを指す野ではなく、SelectedIndexChangedイベントのコードを書き込んだ
ListBox1の配置されているフォームです。


引用:

ちなみに、SelectedValueを使用しているということはValueMemberプロパティを使用しているということでしょうか?
そうでないならSelectedItemのほうを使うとよいでしょう。
今回の書かれた現象としてはなんら変わりありませんけど。



ValueMemberプロパティを使用しています。
大変申し訳ありませんが、まずフォームを閉じるときにSelectedIndexChangedイベント
の発生は、正常ではないのでしょうか。まずそのことを教えてください。
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2007-10-31 16:25
引用:

「Nothingになった理由」は何も選択していない状態でイベントが発生すると
Index:-1
Value:Nothing
になるようですが、フォームを閉じるときにSelectedIndexChangedイベントがなぜ
発生するのでしょうか。ご指摘されていることは、通常発生しないということでしょうか。



例外が起きたときのItems.Countを見てみるとよいでしょう。
発生するかしないかの質問に対しては、「発生する」です。 まだListBoxが生きているからです。>ListBoxにしてみれば自分の仕事ですから。
ちなみに初めてItemsに追加されるタイミングでも発生してるはずです。
だんじり
大ベテラン
会議室デビュー日: 2007/08/10
投稿数: 155
お住まい・勤務地: 神奈川県
投稿日時: 2007-10-31 16:51
まどかさん、ありがとうございます。
「フォームを閉じるときは、まだListBoxが生きていて、ListBox自身の仕事として
フォームが閉じる変化に対してもSelectedIndexChangedイベントを発生させますが、
アイテムを選択したわけではないので
Index:-1
Value:Nothing
となる。」と考えればよいのでしょうか。

「ちなみに初めてItemsに追加されるタイミングでも発生してるはずです。」との事です
が、追加はなんとなくチェンジしたのでイベント発生はありそうな気がします。
このソフトは、リストボックスにLookUpテーブルを設定していまっすので、このあとに
実験してみます。

大変ありがとうございました。

[ メッセージ編集済み 編集者: だんじり 編集日時 2007-10-31 16:54 ]
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2007-10-31 17:21
ListBoxやComboBoxでは、SelectedIndexが -1 であるかどうかの判断は
必須であると言ってもよいです。
各処理の前にガード句として
If ListBox1.SelectedIndex = -1 Then
Exit Sub
End if
または
If ListBox1.SelectedIndex > -1 Then
処理
End If
のどちらかにする癖をつけたほうがよいでしょう。

また、〜Changedイベントはあくまでプロパティ値が変化したという意味でしかありません。
場合によっては、Selected〜プロパティ間に不整合がある場合(タイミング)もあります。
そこら辺のあーだこーだは過去ログにあります。
だんじり
大ベテラン
会議室デビュー日: 2007/08/10
投稿数: 155
お住まい・勤務地: 神奈川県
投稿日時: 2007-10-31 18:02
まどかさん、本当に助かりました
ご指導をもらうまでは、フォームが閉じる時にSelectedIndexChangedイベントは発生す
ることが正常な動作か、または私のコード記述ミスなもカも分らず、大変困っていました。
今年8月から.NETをはじめたばかりで、皆様には常識のようなことが、私にとっては
不可思議なことが沢山あります。

引用:

まどかさんの書き込み (2007-10-31 17:21) より:
ListBoxやComboBoxでは、SelectedIndexが -1 であるかどうかの判断は必須であると
言ってもよいです。各処理の前にガード句として
If ListBox1.SelectedIndex = -1 Then
Exit Sub
End if
または
If ListBox1.SelectedIndex > -1 Then
処理
End If
のどちらかにする癖をつけたほうがよいでしょう。



こんなことも本には書かれていませんし、みんな経験なのでしょうか。
この際、SelectedIndexChangedイベントに関してその動作を徹底的に勉強してみます。
ありがとうございました。
だんじり
大ベテラン
会議室デビュー日: 2007/08/10
投稿数: 155
お住まい・勤務地: 神奈川県
投稿日時: 2007-11-01 11:57
ListBoxに関していろんなテストをしてみました。
その結果を報告すると同時に、追加で質問が発生しました。よろしくご指導下さい。

テスト1.フォームを閉じるときにSelectedIndexChangedイベントは発生します。
そのときの次の返値はNullで、SelectedIndexは -1 となります。
○SelectedItem.ToString
○SelectedValue.ToString
○ListBox1.Text

テスト2.リスト表示のアイテムを追加してもSelectedIndexChangedイベントは発生しません。

テスト3.SelectedItem.ToStringは常に「System.Data.DataRowView」を返します。
ValueMemberを空に設定するとSelectedValueも「System.Data.DataRowView」となる。

テスト4. ListBox1.Textの返値はValueMemberの設定に関係なく選択値が返される

【質問したいこと】
1.ListBoxの説明サイトを見てもフォームを閉じるときにSelectedIndexChanged
イベントは発生することは説明がありません。なぜでしょうか
http://dobon.net/vb/dotnet/control/lbselectitem.html
http://www12.plala.or.jp/dokugaku/main/6/4.html

2.SelectedItem の返値(System.Data.DataRowView)は何を示しているのですか

3.返値をListBox1.Textから取得しても問題ないのでしょうか。

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

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