none
ComboBoxで「'0' の InvalidArgument=Value は 'index' に対して有効ではありません」が発生します RRS feed

  • 質問

  • お世話になります。

     

    OpenFileDialogで選択した一つのファイルのファイル名をComboBoxに設定しています。その後ComboBoxから、表示されているファイル名をdeleteキーで削除し、ComboBoxを空にします(Items.Countが0の状態)。

     

    この状態で、ComboBoxの横の▼ボタンをクリックすると、「アプリケーションのコンポーネントで、ハンドルされていない例外が発生しました。'0' の InvalidArgument=Value は 'index' に対して有効ではありません」が発生します。

    ちなみにComboBoxの枠の部分をクリックしてドロップダウンさせた場合は、この現象は発生しません。

    (DropDownイベントで、Items.Count > 0 の時に先頭ファイル名を設定し、Items.Count = 0 の時は単にExit Subさせてみたのですが結果は変わりませんでした。条件を SelectedIndex > -1 とした場合も同じでした)

     

    どなたか、原因もしくは回避方法をご存知でしたら、ご教授頂けたらと思います。

     

    【開発環境】

    Windows Vista Business(SP1適用)

    VS2005(VB6.0からVB2005へ移行したプロジェクトを使用)

     

    ComboBoxのスタイルは「DropDownList」です。

     

    よろしくお願い致します。

    2008年10月7日 8:02

回答

  • アプリケーションフレームワークの有効無効に関係なく再現できます。

     

    以下に再現用のコードを掲載します。

    (1)(3)のどちらかの処理をすればエラーは出ません。

    (2)の処理ではだめです。

     

    エラー対策コードがあれば1000回以上のループテストに耐えました。

     

    Code Snippet

    Public Class Form1
        Private combobox As New System.Windows.Forms.ComboBox()
        Private cnt As Integer = 0
        ’Private seq As Integer = 0

        Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
            MyBase.OnLoad(e)

            combobox = New System.Windows.Forms.ComboBox()
            combobox.DropDownStyle = ComboBoxStyle.DropDownList
            ’AddHandler combobox.KeyDown, AddressOf ComboBox_KeyDown
            Me.Controls.Add(combobox)

            Me.components = New System.ComponentModel.Container
            Dim tm As New System.Windows.Forms.Timer(Me.components)
            AddHandler tm.Tick, AddressOf ComboBox_KeyDown
            tm.Interval = 100
            tm.Start()
        End Sub

        Private Sub ComboBox_KeyDown(ByVal sender As Object, ByVal e As EventArgs)
            combobox.DroppedDown = False
            combobox.Items.Add("TEST")
            combobox.SelectedIndex = 0
            combobox.DroppedDown = True
            MyBase.OnKeyDown(New KeyEventArgs(Keys.Down))
            'combobox.DroppedDown = False '(1)
            combobox.Items.Remove(combobox.Text)
            'combobox.SelectedIndex = -1 '(2)
            combobox.DroppedDown = False
            'combobox.SelectedIndex = -1 '(3)
            cnt += 1
            Console.WriteLine("START:{0} COUNT:{1}", combobox.SelectedIndex, cnt)
            combobox.DroppedDown = True
        End Sub
    End Class

     

     

    #2008/10/09 19:07 余計なコードをコメントアウトしました

    2008年10月9日 3:47

すべての返信

  • これでどうでしょうか?

    Code Snippet
    Public Class Form1
        Private combobox As New System.Windows.Forms.ComboBox()

        Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
            MyBase.OnLoad(e)

            combobox = New System.Windows.Forms.ComboBox()
            combobox.DropDownStyle = ComboBoxStyle.DropDownList
            combobox.Items.Add("TEST")
            combobox.SelectedIndex = 0
            AddHandler combobox.KeyDown, AddressOf ComboBox_KeyDown

            Me.Controls.Add(combobox)
        End Sub

        Private Sub ComboBox_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
            If e.KeyCode = Keys.Delete Then
                combobox.DroppedDown = False
                combobox.Items.Remove(combobox.Text)
            End If
        End Sub
    End Class

    2008年10月7日 16:52
  • gekkaさんご回答ありがとうございます。

     

    KeyDwonイベントで、Items.Count = 0 の時にcombobox.DroppedDown = Falseを入れてみたのですが、残念ながら、現象は変わらず発生してしまいました。

    デバッグしてみると、コンボボックスが空になった時点で、combobox.DroppedDownは自動的にFalseになっていました。

    うーんこれは悩みそうです。

    また何かお気づきの点がありましたら、ご指摘頂ければと思います。

    よろしくお願い致します。

    2008年10月8日 14:09
  • バグっぽい気もします。どうやら[アプリケーション フレームワークを有効にする] のチェックが影響しているようです。

     

    System.Windows.Forms.ComboBox can throw System.ArgumentOutOfRangeException in rare cases
    https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=355454&wa=wsignin1.0

    2008年10月8日 15:04
    モデレータ
  • 私がテストした限りでは、ドロップダウンのリスト部分のウィンドウにフォーカスがある状態で、Deleteすると要素が無いので持つはずがないフォーカスが残ってしまっている場合があります。
    その状態からドロップダウンを閉じて、再度開こうとするとエラーになりました。
    コンボボックス枠からでも▼でも、Alt+↓でもエラーになります。

    フォーカスが残るのは何かしらの不具合だとしても、Deleteする前にリストを閉じてフォーカスが残らないようDroppedDown = Falseを入れました。
    このコードを追加して100回ほど試しましたがエラー再現できません。
    これ以上にまれな頻度のエラーで発生するエラーだとすると再現するのも大変ですね。

    2008年10月8日 17:04
  •  gekka さんからの引用

    私このコードを追加して100回ほど試しましたがエラー再現できません。
    これ以上にまれな頻度のエラーで発生するエラーだとすると再現するのも大変ですね。

     

    上で私が示したリンク先のコネクトでも、再現しないということで一旦クローズしています。しかし、その後、「アプリケーションフレームワークを有効にする」のチェックが外れていると発生するようなことが書かれています。

    想像ですが、VB6から移行してきたプロジェクトということですので、ひょっとするとMainメソッドが追加され、そこからアプリケーションを実行するために、「アプリケーションフレームワークを有効にする」のチェックが外れているのかもしれません。

    2008年10月9日 0:36
    モデレータ
  • アプリケーションフレームワークの有効無効に関係なく再現できます。

     

    以下に再現用のコードを掲載します。

    (1)(3)のどちらかの処理をすればエラーは出ません。

    (2)の処理ではだめです。

     

    エラー対策コードがあれば1000回以上のループテストに耐えました。

     

    Code Snippet

    Public Class Form1
        Private combobox As New System.Windows.Forms.ComboBox()
        Private cnt As Integer = 0
        ’Private seq As Integer = 0

        Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
            MyBase.OnLoad(e)

            combobox = New System.Windows.Forms.ComboBox()
            combobox.DropDownStyle = ComboBoxStyle.DropDownList
            ’AddHandler combobox.KeyDown, AddressOf ComboBox_KeyDown
            Me.Controls.Add(combobox)

            Me.components = New System.ComponentModel.Container
            Dim tm As New System.Windows.Forms.Timer(Me.components)
            AddHandler tm.Tick, AddressOf ComboBox_KeyDown
            tm.Interval = 100
            tm.Start()
        End Sub

        Private Sub ComboBox_KeyDown(ByVal sender As Object, ByVal e As EventArgs)
            combobox.DroppedDown = False
            combobox.Items.Add("TEST")
            combobox.SelectedIndex = 0
            combobox.DroppedDown = True
            MyBase.OnKeyDown(New KeyEventArgs(Keys.Down))
            'combobox.DroppedDown = False '(1)
            combobox.Items.Remove(combobox.Text)
            'combobox.SelectedIndex = -1 '(2)
            combobox.DroppedDown = False
            'combobox.SelectedIndex = -1 '(3)
            cnt += 1
            Console.WriteLine("START:{0} COUNT:{1}", combobox.SelectedIndex, cnt)
            combobox.DroppedDown = True
        End Sub
    End Class

     

     

    #2008/10/09 19:07 余計なコードをコメントアウトしました

    2008年10月9日 3:47
  • テストしてみました。なるほど、確かにアプリケーションフレームの有効無効は関係ないようです。私が紹介したコネクトの情報とはまた別の問題のようです。失礼いたしました。

    今回の件をコネクトにフィードバックした方が良いかもしれません。

     

    #ところでご提示されたコードですが、そのままですとデリゲートのシグニチャが違うと言われてコンパイルできませんでした。combobox.KeyDownのデリゲートのシグニチャにおける2番目の引数の型がSystem.Windows.Forms.KeyEventArgsになっているからだと思いますが、何か特別なことをすると上記のコードがコンパイルできるようになるのでしょうか?

     

    2008年10月9日 5:48
    モデレータ
  • お世話になります。

     

    皆様ありがとうございます!!

     

    gekkaさんご提示のコード(1)の方法で現象が発生しなくなりました。

        combobox.DroppedDown = False
        combobox.Items.Remove(combobox.Text)

    Items.Removeの前にDroppedDown = Falseを入れるのがミソだったんですね。

    最初にコードを提示して頂いていたにもかかわらず、Items.Removeの後ろに入れて、直らないと騒いでいました。すいません。

    処理順序にも以後気をつけます。

     

    ありがとうございました!!

    2008年10月9日 6:25

  •  trapemiyaさんからの引用

    #ところでご提示されたコードですが、そのままですとデリゲートのシグニチャが違うと言われてコンパイルできませんでした。
    combobox.KeyDownのデリゲートのシグニチャにおける2番目の引数の型がSystem.Windows.Forms.KeyEventArgsになっているからだと思いますが、何か特別なことをすると上記のコードがコンパイルできるようになるのでしょうか?


    おっしゃるとおり、2003,2005で試したら確かにエラーになりますね。
    c#のイベント追加では以前から厳密に一致しなくてもできましたし、Option Strict Onでも警告してこないから気にせず使ってました。
    特に設定はした覚えがないので、2008から出来るようになった「厳密でないデリゲート変換」のおかげでしょうか。
    2008年10月9日 10:05
  • なるほど。「厳密でないデリゲート変換」は知りませんでした。これはこれで便利かもしれませんね。ありがとうございました。

    2008年10月10日 4:23
    モデレータ
  • ちなみにC#ではどうかと気になったので調べてみました。VS2005では問題なく実行されますが、VS2003ではKeyDownメソッドはデリゲート型 'void System.Windows.Forms.KeyEventHandler(object, System.Windows.Forms.KeyEventArgs)' と一致しませんという趣旨のメッセージが出て、コンパイルできませんでした。

    C# 2.0で匿名メソッドが導入されましたが、匿名メソッドはいろいろなシグニチャを持つデリゲートに変換されますから、ついでにデリゲートもデリゲート変換されるようになったのかもしれません。このことを明確に書いてある文章を見つけられませんでした。

    2008年10月10日 7:31
    モデレータ