none
コンボボックスのイベントについて RRS feed

  • 質問

  • おはようございます。

    2つのコンボボックスを用意してあり、(コンボA、コンボBとします。)コンボAはコンボBの値(SelectedValue)により、変更をさせたいと思っています。

    それぞれのコンボボックスは建物のフロアと部屋番号となっており、(コンボAがフロア、コンボBが部屋番号)、コンボAは画面上でわかりやすくするために
    用意してあるだけのものです。

    それぞれのコンボボックスにはDBからのデータをDataTableに取得して表示を行っています。

    コンボボックスのSelectedValueChangedイベントでの変更は何とかできたのですが、直接コンボボックスに値を入力した場合にフロアの表示が
    変わらないことに気付き、悩んでおります。(DataTableにない値を入力した場合はエラーとなるようにしてあります。)

    ValidatedイベントやTextChangeイベントを試したところ、1文字入力するたびにイベントが発生してしまい、目的の文字の入力ができません。

    LostFocusイベントにSelectedValueChangedイベントのコードをそのままコピーしたところ、SelectedValueChangedイベントではエラーが起きないのですが
    「オブジェクト参照がオブジェクト インスタンスに設定されていません。」
    とのエラーが出ます。

    実行しているコードは以下の通りです。

    '病室の所属する病棟を病棟コンボボックスに表示する
            Dim FoundRow As DataRow

            If Me.cbo_Room.SelectedIndex <> 0 Then
                If retRoomDT IsNot Nothing Then
                    FoundRow = retRoomDT.Rows.Find(Me.cbo_Room.SelectedValue.ToString)

                    If FoundRow IsNot Nothing Then
                        If Me.cbo_Floor.SelectedValue.ToString <> CStr(FoundRow("Floor_id")) Then
                            Me.cbo_Floor.SelectedValue = FoundRow("Floor_id")
                        End If
                    End If
                End If
            End If

    自分でもいろいろと試しているのですが、なかなかうまくいきません。
    どうか、アドバイスお願いします。

    2009年7月20日 21:52

回答

  • おことわり:試していないので、推測に基づいています。

    LostFocusイベントにSelectedValueChangedイベントのコードをそのままコピーしたところ、SelectedValueChangedイベントではエラーが起きないのですが
    「オブジェクト参照がオブジェクト インスタンスに設定されていません。」
    とのエラーが出ます。

    NullReferenceExceptionという例外が発生しているのだと思いますが、そのときに黄色くなっている行近辺に問題があるはずです。
    もしくは、例外の詳細を見る等から、StackTraceプロパティで例外がスローされたのはどのコードかを知ることができます。

    さて、どんな問題が起きているのかの予想です。
    まず、SelectedIndex は何も選択されていないことを示す、-1になっていませんか?
    また、-1 なので <> 0の If ブロックの中に入り、SelectedValue が Nothing になっていませんか?

    DataTable にない値を入力したときにエラーにするようにしている処理がどのように実現されているかどうか分かりませんが、とりあえず、ぱっと見た限りでの問題点として挙げています。
    # もしかしたら、私が知らないだけでどこかで補正されるコードがあるのかもしれませんが…。


    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    • 回答としてマーク TI-cb400 2009年7月29日 22:37
    2009年7月21日 14:41
    モデレータ
  • ValidatedイベントやTextChangeイベントを試したところ、1文字入力するたびにイベントが発生してしまい、目的の文字の入力ができません。

    なぜ入力できないようになっているのかわからないのですが、コンボBは何でも入力できるようにしておき、1文字ごとに該当する部屋番号が無いかをチェックして、あればコンボAを更新しにいくロジックで十分のように思います。もし部屋番号の桁数が決まっているのでしたら、その桁数になった時に初めて部屋番号の存在チェックをしても良いと思います。

    以下は参考までですが、
    考え方として、

    フロアA-----+-----部屋番号101
                    |
                    +-----部屋番号102

    フロアB-----+-----部屋番号201
                    |
                    +-----部屋番号202

    フロアC-----+-----部屋番号301
                    |
                    +-----部屋番号302

    のようになっているわけですから、フロアもしくは部屋番号に一致すればその塊(フロアと部屋番号のセット)に表示を移動すれば良いと思います。
    したがって、この塊の移動をコントロールするクラスを一つ作って、それに管理させれば良いかもしれません。
    働きとしては、フロアもしくは部屋番号を受け取り、実在すればそれが実在する塊に移動する、つまり、2つのコンボボックスの表示を切り替えるというものです。このクラスは2つのコンボボックスの同期を取るバインディングのように動作します。

    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク TI-cb400 2009年7月29日 22:37
    2009年7月22日 4:59
    モデレータ
  • また、コンボボックスに直接値を入力した場合にSelectedValueはいつ変更になるのでしょうか。
    それとも、変更されることはないのでしょうか。
    直接入力された値が既存のアイテムと一致するかどうかと、一致するのであればそれを選択する動作はご自身で書かないと駄目なのでは?
    (DataTableと組み合わせて使ったことがないので、私は便利な機能を見逃している可能性があります)

    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    • 回答としてマーク TI-cb400 2009年7月29日 22:37
    2009年7月23日 22:53
    モデレータ

すべての返信

  • おことわり:試していないので、推測に基づいています。

    LostFocusイベントにSelectedValueChangedイベントのコードをそのままコピーしたところ、SelectedValueChangedイベントではエラーが起きないのですが
    「オブジェクト参照がオブジェクト インスタンスに設定されていません。」
    とのエラーが出ます。

    NullReferenceExceptionという例外が発生しているのだと思いますが、そのときに黄色くなっている行近辺に問題があるはずです。
    もしくは、例外の詳細を見る等から、StackTraceプロパティで例外がスローされたのはどのコードかを知ることができます。

    さて、どんな問題が起きているのかの予想です。
    まず、SelectedIndex は何も選択されていないことを示す、-1になっていませんか?
    また、-1 なので <> 0の If ブロックの中に入り、SelectedValue が Nothing になっていませんか?

    DataTable にない値を入力したときにエラーにするようにしている処理がどのように実現されているかどうか分かりませんが、とりあえず、ぱっと見た限りでの問題点として挙げています。
    # もしかしたら、私が知らないだけでどこかで補正されるコードがあるのかもしれませんが…。


    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    • 回答としてマーク TI-cb400 2009年7月29日 22:37
    2009年7月21日 14:41
    モデレータ
  • ValidatedイベントやTextChangeイベントを試したところ、1文字入力するたびにイベントが発生してしまい、目的の文字の入力ができません。

    なぜ入力できないようになっているのかわからないのですが、コンボBは何でも入力できるようにしておき、1文字ごとに該当する部屋番号が無いかをチェックして、あればコンボAを更新しにいくロジックで十分のように思います。もし部屋番号の桁数が決まっているのでしたら、その桁数になった時に初めて部屋番号の存在チェックをしても良いと思います。

    以下は参考までですが、
    考え方として、

    フロアA-----+-----部屋番号101
                    |
                    +-----部屋番号102

    フロアB-----+-----部屋番号201
                    |
                    +-----部屋番号202

    フロアC-----+-----部屋番号301
                    |
                    +-----部屋番号302

    のようになっているわけですから、フロアもしくは部屋番号に一致すればその塊(フロアと部屋番号のセット)に表示を移動すれば良いと思います。
    したがって、この塊の移動をコントロールするクラスを一つ作って、それに管理させれば良いかもしれません。
    働きとしては、フロアもしくは部屋番号を受け取り、実在すればそれが実在する塊に移動する、つまり、2つのコンボボックスの表示を切り替えるというものです。このクラスは2つのコンボボックスの同期を取るバインディングのように動作します。

    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク TI-cb400 2009年7月29日 22:37
    2009年7月22日 4:59
    モデレータ
  • ご返信ありがとうございます。

    Azuleanさんへ

    ご指摘の通り、SelectecIndexがー1となっていました。
    さらにSelectedValueが空白となっており、そのため、エラーとなっているようです。

    trapemiyaさんへ
    入力できなかったのは、Varidatingイベントに記述したときのことで、1文字入力後とに存在する部屋番号かどうかのチェックというものを
    組み込んでいかったため、目的の部屋番号の入力までたどり着くことができなかったということです。

    また、ご提示いただいたフロアと部屋番号を管理するクラスというものが良くわからないので、少し考えてみたいと思います。

    単純に考えて、現在は、コンボボックスのSelectecValueをキーとしてフロアを取得するようにしていたのですが、それを部屋番号をもとに
    すれば、現在のコードの改良ですむと思います。
    (ただ、今後の修正を考えるとtrapemiyaさんがおっしゃるような方法を採用しておくほうが良いと思うので挑戦をしてみたいと思います。)

    また、コンボボックスに直接値を入力した場合にSelectedValueはいつ変更になるのでしょうか。
    それとも、変更されることはないのでしょうか。

    Varidated、Leaveイベントでチェックをしてみましたが、変更はされていないというよりも、空白となってしまうようでした。

    2009年7月23日 22:38
  • また、コンボボックスに直接値を入力した場合にSelectedValueはいつ変更になるのでしょうか。
    それとも、変更されることはないのでしょうか。
    直接入力された値が既存のアイテムと一致するかどうかと、一致するのであればそれを選択する動作はご自身で書かないと駄目なのでは?
    (DataTableと組み合わせて使ったことがないので、私は便利な機能を見逃している可能性があります)

    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    • 回答としてマーク TI-cb400 2009年7月29日 22:37
    2009年7月23日 22:53
    モデレータ
  • お返事が遅くなりました。

    trapemiyaさんがおっしゃるようにひとつクラスを作り対応するようにしました。

    どうも、ありがとうございました。
    2009年7月29日 22:37