【VB2005】動的に作成されたComboBoxをイベントハンドラへ関連づけする際の問題

このQ&Aのポイント
  • VB5.0から2005に乗り換えたばかりの初心者が、動的に作成されたComboBoxをTextChangedイベントに関連づける際の問題について質問しています。
  • 実行時に動的に作成されるComboBoxをイベントハンドラへ関連付ける際に、TextChangedイベントが認識されない問題に悩んでいます。
  • 質問者は、ComboBoxのリストを選択する際に、同じ選択肢を選んだ場合に色が変わる機能を実装したいとしています。
回答を見る
  • ベストアンサー

【vb2005】 動的に作成されたComboBoxをイベントハンドラへ関連づけする際の問題

おはようございます。 VB5.0を1週間ほどかじって現在2005に乗り換えたばかりのド初心者です。 (用語の使い方などが間違っているかもしれません。おかしなところは指摘していただけるとありがたいです) 実行時に動的(?)に作成されたComboBoxをイベントハンドラへ関連付けようとしているのですが、ClickやLeaveなどで関連づけると正常に動作するのにTextChangedの場合になぜか認識してもらえません。 原因の見当がまったくつかず、困り果てています。 内容は、まずボタンを押すとコンボボックスが2つずつ追加されます。そのコンボボックスのリストを選ぶ際、追加されたふたつが同じものを選んでいると色が変わるようにするものです。 下にそのソースを簡潔にしたサンプルを記述させていただきます。 間違いの指摘や、うまくいかない原因、アドバイスなど頂ければ幸いです。 (formにはButton1というボタンが一つだけあります。) Dim Index As Integer Private CBox1() As ComboBox Private CBox2() As ComboBox Private Sub CBB_LT_SameErroCheck(ByVal sender As System.Object, ByVal e As System.EventArgs) Dim T As Integer T = sender.Tag If CBox1(T).Text = "" Then Exit Sub End If If CBox1(T).Text = CBox2(T).Text Then CBox1(T).BackColor = Color.Red CBox2(T).BackColor = Color.Red Else CBox1(T).BackColor = Color.White CBox2(T).BackColor = Color.White End If End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ReDim Preserve CBox1(Index) ReDim Preserve CBox2(Index) SuspendLayout() CBox1(Index) = New ComboBox CBox2(Index) = New ComboBox With CBox1(Index) .Location = New Point(105, Index * 20) .Size = New Size(95, 20) .DropDownStyle = ComboBoxStyle.DropDownList .Tag = Index .Items.Add("List1") .Items.Add("List2") End With With CBox2(Index) .Location = New Point(200, Index * 20) .Size = New Size(95, 20) .DropDownStyle = ComboBoxStyle.DropDownList .Tag = Index .Items.Add("List1") .Items.Add("List2") End With 'AddHandler CBox1(Index).Click, AddressOf CBB_LT_SameErroCheck 'AddHandler CBox2(Index).Click, AddressOf CBB_LT_SameErroCheck AddHandler CBox1(Index).TextChanged, AddressOf CBB_LT_SameErroCheck AddHandler CBox2(Index).TextChanged, AddressOf CBB_LT_SameErroCheck Me.Controls.Add(CBox1(Index)) Me.Controls.Add(CBox2(Index)) ResumeLayout(False) Index += 1 End Sub

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

まずは関係ない話から。 Option Strict Onの時, >T = sender.Tag (T:Integer,sender:Object,ObjectはTagプロパティを持たないから駄目だろと怒られた。 そのため、当方環境での検証において 該当部分を T = DirectCast((DirectCast(sender, ComboBox)).Tag, Integer) と置き換えた。なお,System.Windows.Forms名前空間が読み込まれていない場合,System.Windows.Forms.ComboBoxと記述する必要がある。 ====== まだ読んでいる途中です。 ComboBoxStyle.DropDownListの場合,TextChangedは発生しないんだとか何とか。ComboBoxStyle.DropDownの場合,当方環境で発生が確認できた。 変わりにSelectedIndexChangedやSelectedValueChangedを使えとさ。 http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=218564&SiteID=1 http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=10399&forum=7 http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=10399&forum=7

ponknight
質問者

お礼

お早いご返信ありがとうございます。 仰るとおり、SelectedValueChangedを使ったところ思い通りの動作をしてくれました!助かりました! しかし解せないのが、ComboBoxStyle.DropDownListをデザイン時に配置しデザイン時にTextChangedイベントハンドラへ関連付けした場合と、デザイン時に配置したものを実行時にイベントハンドラへ関連付けした場合は何故か上手く動いたんです。 コントロールを実行時に動的に追加した場合のみこのような事になってしまったので余計に悩んでしまっておりました。 いくつか上げていただいた参考記事(英語は読めませんでした・・・)に似たような事が書いてありましたが、バグなんでしょうか。 何はともあれ、解決法を導いてくださった事、感謝いたします。 ありがとうございます。

その他の回答 (2)

回答No.3

>しかし解せないのが、(中略)デザイン時に配置したものを実行時にイベントハンドラへ関連付けした場合は何故か上手く動いたんです 再現しました。なんじゃこりゃ!? 解決策にいたらず申し訳ないですが,一応再現報告はしておきます。 俺自身も更なる識者の回答を待ちたいと思います

ponknight
質問者

お礼

>解決策にいたらず申し訳ないですが, とんでもないです。 ご教授いただいた方法でプログラム自体は正常に動かすことができるようになり、現在は順調に作業が進められています。 その上、再現をし確認までしてくださった事、とても感謝しております。 今回の件の根本的な原因について、何かご存知の方がいらっしゃるかもしれませんので、しばらくこの質問は締め切らずに置いてみようかと思います。 お互い有益な情報が得られることを祈って、しばし待ちましょう。 ご返信ありがとうございました。

回答No.2

二つ追記。 ●当方の環境では Forumで述べられている「マウスによる操作」によっても TextChangedイベントは発生していませんでした。 ●CBB_LT_SameErrorCheckでなく CBB_LT_SameErroCheckなのは 意図的ですか?

ponknight
質問者

お礼

ご指摘ありがとうございます。 CBB_LT_SameErrorCheckが正しく、「r」が抜けているのは私のタイプミスでした。 幸い、今回はこれに起因する問題は発生しなかったようですが、タイプミスなどの単純な誤りが問題になってしまう場面もあるかと思います。 今後はもっと気をつけるよう心がけます。

関連するQ&A

  • VB2008 comboboxを連動させた際のエラー

    先日より取り組んでいる顧客検索プログラムですが、combobox1でササキを選ぶとcombobox2には北海道、combobox3には札幌市と表示させたいと思います。先日もアドバイスをいただきそれを参考にすすめていますが、「'0' の InvalidArgument=Value は 'SelectedIndex' に対して有効ではありません。 パラメータ名: SelectedIndex」というエラーが出てしまいどうしても解決出来ません。このエラーの後さらにデバッグすると思ったとおりに動作するのですが、エラーを解決するにはどう対処すると良いのでしょうか?下記が現在のソースとなります。どうかアドバイスをお願い致します。 ササキ,北海道,札幌市, スズキ,東京都,あきる野市, サトウ,愛知県,名古屋市, ハヤシ,北海道,旭川市, が TextFile1.txtです。 Imports System.IO ------------ Public Class Form1 Private Sub Form1_Load(省略~ Dim fn As String = "C:\TextFile1.txt" Dim read As System.IO.StreamReader = My.Computer.FileSystem.OpenTextFileReader(fn, System.Text.Encoding.Default) Dim dline() As String Dim namelist As ArrayList = New ArrayList() Dim adr1list As ArrayList = New ArrayList() Dim adr2list As ArrayList = New ArrayList() dline = Split(read.ReadToEnd, vbCrLf) Dim srcary() As String Dim i As Integer For i = LBound(dline) To UBound(dline) srcary = Split(dline(i), ",") namelist.Add(srcary(0)) adr1list.Add(srcary(1)) adr2list.Add(srcary(2)) Next ComboBox1.DataSource = namelist ComboBox1.SelectedIndex = -1 ComboBox1.Text = "名前" ComboBox2.DataSource = adr1list ComboBox2.SelectedIndex = -1 ComboBox2.Text = "住所1" ComboBox3.DataSource = adr2list ComboBox3.SelectedIndex = -1 ComboBox3.Text = "住所2" End Sub ------------- Private Sub ComboBox1_SelectedIndexChanged(省略~ If ComboBox1.SelectedIndex > -1 Then ComboBox2.SelectedIndex = ComboBox1.SelectedIndex Else ComboBox2.Text = "" End If End Sub

  • DatagridviewComboboxCellについて聞きたいですが

    DatagridviewComboboxCellについて聞きたいですが、 各セルのコンボボックスに違い値を入れたいけど、以下のエラーが出ました。 "指定されたセルはグリッドにすでに属しています"。 ソース例: Dim Reader As FileReader = New FileReader("C://text.txt") Dim cbb as New DatagridviewComboboxCell() Dim cbb1 as New DatagridviewComboboxCell() Dim strA as String = "" Dim t as integer = 0 Me.Controls.Add(Dtgrdview) Dtgrdview.ColumnCount = 5 . (省略) For i as Integer = 0 to 10 Select case strA Case "A" cbb.Items.Add(Cstr(i)) Case "B" cbb1.Items.Add(Cstr(i+1)) End Select Next With Dtgrdview.Rows While not Reader.EndofData     Dim _readFile As readFile = New readFile(Reader.ReadFields()) '(readFile.vbは別) Dim row As String() = _ {_readFile.Class,_readFile.Name,_readFile.Year,_readFile.Add} ' Dtgrdview.Rows.Add(row) Select Case _readFile.ID Case "A" Dtgrdview.Rows(t).Cells(4) = cbb ==> t= 1 エラーが出る Case Else Dtgrdview.Rows(t).Cells(4) = cbb1 End Select t += 1 End While ReadFile.Close() End With 解決方法を教えてください。ありがとうございます。

  • VB2010でイベントハンドラの動的登録

    VB2010で目標はフォーム上で作成したLINESHAPEをクリックして消去する事です 下記のようにコードを書いてみました Imports Microsoft.VisualBasic.PowerPacks Public Class Form1 Private px1 As Integer = 0 Private px2 As Integer = 0 Private py1 As Integer = 0 Private py2 As Integer = 0 Private curv As LineShape Private a As Boolean = True Private flg As Boolean = True Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load // 座標と始点・終点フラグの初期化 px1 = 0 px2 = 0 py1 = 0 py2 = 0 a = True End Sub Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click     // SHAPECONTAINER の用意 Dim canvasx As New ShapeContainer    // LINESHAPE の用意 Dim ls1 As New LineShape      // LineShape インスタンス設定 canvasx.Parent = Me ls1.Name = "curv" ls1.Parent = canvasx ls1.BorderColor = Color.Lime ls1.SelectionColor = Color.Green ls1.X1 = px1 ls1.X2 = px2 ls1.Y1 = py1 ls1.Y2 = py2    // ShapeContainer のコントロールコレクションへの追加 Me.Controls.Add(canvasx) End Sub Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click     // 座標と始点・終点フラグの初期化 px1 = 0 px2 = 0 py1 = 0 py2 = 0 a = True End Sub Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click //CURV_CLiCKのイベントの登録 AddHandler curv.Click, AddressOf curv_Click End Sub Private Sub Form1_Click(sender As System.Object, e As System.EventArgs) Handles MyBase.Click     // Lineの座標を拾う Dim Pos As Point = Me.PointToClient(Windows.Forms.Cursor.Position) If a = True Then px1 = Pos.X py1 = Pos.Y a = False Else px2 = Pos.X py2 = Pos.Y End If End Sub Private Sub curv_Click(sender As System.Object, e As System.EventArgs) // クリックされたLineShapeの消去のつもり、テスト未完 For Each obj In Me.Controls If obj = sender Then obj = Nothing End If Me.Refresh() Next End Sub End Class 書かれた直線をクリックしても何も起きません。LineShape は確かにハイライト色に変化するのですが、イベントが発生しません なにとぞご教授を

  • VB2010において同様のイベントを設定する。

    現在、VisualBasic2010を用いてPanel1~Panel4をPanel5へ移動させて図形を作成させるコードを書いております。 今後Panel1~Panel4をPanel5だけでなく、Panel6,Panel7にも同様に移動させたいと考えておりますが、やりかたがわかりません。 画像はPanel5へ移動させたものです。同様に下に配置したPanel6へも移動させたいです。 わかる方がおられましたら、お力添えいただけると助かります。 Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Panel5.AllowDrop = True End Sub Private Sub Panel1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown, Panel2.MouseDown, Panel3.MouseDown, Panel4.MouseDown sender.DoDragDrop(sender, DragDropEffects.Move) End Sub Private Sub Panel5_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel5.DragDrop Dim srsPnl As Panel = e.Data.GetData(GetType(Panel)) Dim dstPnl As New Panel dstPnl.Size = srsPnl.Size dstPnl.Location = Panel5.PointToClient(CursorPosition) 'New Point(e.X, e.Y) dstPnl.BackColor = srsPnl.BackColor AddHandler dstPnl.MouseDown, AddressOf dstPnl_MouseDown AddHandler dstPnl.MouseMove, AddressOf dstPnl_MouseMove Panel5.Controls.Add(dstPnl) End Sub Private Sub Panel5_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel5.DragEnter If e.Data.GetDataPresent(GetType(Panel)) Then e.Effect = DragDropEffects.Move End If End Sub Private previousPos As Point Private Sub dstPnl_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown previousPos = CursorPosition() End Sub Private Sub dstPnl_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) If e.Button = Windows.Forms.MouseButtons.Left Then Dim nowPos As Point = CursorPosition() DirectCast(sender, Panel).Left += nowPos.X - previousPos.X DirectCast(sender, Panel).Top += nowPos.Y - previousPos.Y Console.WriteLine(nowPos.X & "-" & previousPos.X) previousPos = nowPos End If End Sub Function CursorPosition() As Point Return New Point(CInt(Cursor.Position.X / 10) * 10, CInt(Cursor.Position.Y / 10) * 10) End Function End Class これが現在書いているコードです。

  • ComboBoxについて

    ComboBoxのアイテムリストからアイテムを選んだら 選んだアイテムに対応した別の文字列 をComboboxに表示したいと思います。 動き的には Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load  ComboBox1.Text = ""  ComboBox1.Items.Add("000")  ComboBox1.Items.Add("001")  ComboBox2.Text = ""  ComboBox2.Items.Add("0個目")  ComboBox2.Items.Add("1個目")  ComboBox2.Visible = False End Sub Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged  Select Case ComboBox1.SelectedIndex   Case 0    ComboBox1.Visible = False    ComboBox2.Visible = True    ComboBox2.SelectedIndex = 0   Case 1    ComboBox1.Visible = False    ComboBox2.Visible = True    ComboBox2.SelectedIndex = 1  End Select End Sub Private Sub ComboBox2_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox2.GotFocus  ComboBox1.Visible = True  ComboBox1.DroppedDown = True  ComboBox2.Visible = False End Sub こんな感じで、ComboBoxを二つ使えば実現できるのですが一つだけでも実現できる方法が ありましたら、教えてくださいませ。

  • VBのEVENT発生とCONTROLの有効範囲

    visual basicのeventとcontrolについての質問です。  初心者で苦労しています。以下のようなcodeingをしましたが上手く行きません。宜しくお願いします。 1.下記のcall updatefileによりupdatefile内でcombobox内のdataを設定します。これは次のdialogで   設定どおりに出ています。しかし元のsub startdialog1に帰ってdialogを表示してみるとcombobox   内は空となっています。  subroutineが変わるとformの controlは消えるのでしょうか。   もしそうならどの様にすれば良いのでしょうか。   (pushdata変数等をpublicとして再度comboに入れることもやりましたがNG) 2.STARTDIALOG1の初めに RADIO BUTTONの変更のCODEが有りますが、此処でEVENTが    発生しUPDATEFILEに行きます。    DIALOGを出すまでは初期値を設定しDIALOG上でCLICK等して変更をするCODEなので    不具合です。 (ほかにもいろいろ同じCODEが入っていますので)    CODE上の設定変更はEVENTが発生しないように、DIALOGからの変更はEVENT発生としたい    のですがどの様にしたら良いでしょうか。(普通そうなので何か勘違いしてるかも)   INTERNETで見るとAddHandler,AddressOf,REmoveHandlerなどが記載されていますが、    書き方と何処に書くのか判りません。(本当に必要かも?)    よろしくお願いします。    (以下のcodeは読みやすいように簡略化しています、code errorは大目に見て下さい。 ---------------------Form1.vbに記載---------------------------------------    Sub STARTDIALOG1()    '此処から処理が始まる with cform2 as Fform2 .Radio_btn1.Checked = True  ’ここへくるとbuttonのeventが発生,routineにいき,updatefileへいく Call UpdatePfile(1) 'ここはcomboboxの初期値を設定する(UPDATEPFILEを使う) .ShowDialog()     ’UpdatateFileでは入っていたがCOMOBOXの中は空になっている               この後comboboxのdataの選択などをdialogue上で設定値を変更する。 end with end sub -----------------------form1.vbに記載---------------------------------- sub UpdatePfile(ByVal cntlNO) 'PushDataはこの前にREADして設定している、keがそのDATAの個数 For k = 1 To ke cForm2.Combo_P.Items.Add(pushdata(k)) ’COMBOBOX Comb_Pに一覧として入れる Next k cForm2.ShowDialog()   'ここではCOMBOBOXにPUSHDATAが入ったLISTがでる end sub --------------------------------------------------------------------------- DisalogはForm2に作成    radioボタン Radio_btn1とRadio_btn2,combobox combo_P等をsetしている '---------------------------Form2.vbに記載------------------------------------ Private Sub push_button(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Radio_BTN1.CheckedChanged,Radio_BTN2.CheckChanged Dim cls As Form1 RDBTN = 1 If RDBTN > 0 Then Call cls.UpdatePfile(RDBTN) end Sub

  • 実行時追加したコントロールの識別

    VB2008を使用しています。 プログラム実行中に追加したコントロールをどのように識別すればいいのかがわからなくて困っています。 例えば以下のようにすると、 itemsが1と2のコンボボックスが10個できますが、 すべてNewComboBoxという名前のコントロールのため、 最終的にそれぞれ1か2どちらを選択したかを知りたいときに、 10個のコントロールをどのように識別すればよいかわかりません。 Dim NewComboBox As ComboBox = New ComboBox() For i = 1 To 10 NewComboBox = New ComboBox() NewComboBox.Items.Add(1) NewComboBox.Items.Add(2) NewComboBox.Location = New Point(5, 5 + (24 * (i - 1))) Me.Controls.Add(NewComboBox) Next 説明が不明瞭であるかもしれませんが、 お分かりの方いらっしゃいましたら、ご回答願います。

  • コンボボックスで日本語入力をハンドルするとき

    またよろしくお願いいたします。 先月よりまたぜんぜんやったことのない言語をいじることになってしまいました。 Visual Studioってけっこうヒント出してくれるので、ひーこら言いながら書けてはいますが、ここは解決できません…。 ネット内を探してもありそうで見つからないんで、この場をお借りいたします。 .NET 2005 の Visual Basic についてです。 ' ------例 Class Form1 As Form  Dim i As Integer  Dim cmb(99) As Combobox  For i = 0 To 99   AddHandler cmb(i).TextChanged, AddressOf cmb_TextChanged  Next i   ...  Sub cmb_TextChanged( なんとかかんとか )   ...   Msgbox("入力検知")  End Sub End Class 抜き出すとこんなようなコードのはずですが、要するに、複数のコンボボックスにTextChangedのイベントハンドラを仕組んだだけです。 これで「できた!」と思ってたのですが、実行してみると、1文字ずつ入力するぶんにはいっこうに問題ないんです。ところが日本語変換を経由してやると、いっぺんに2文字以上入ります。 そのとき、例えば「生麦生米生卵」と変換して入力すると、6回ハンドルされて6回メッセージが出てきます。 ちょっとこれだとうるさいです。 ので、ハンドルが1回だけになるようなことって、可能なのでしょうか。 なお、入力は手入力する場合の他に、プログラム上から複数のボックスへ入力する場合もあります。 重ねてよろしくお願いいたします。m(__)m

  • ComboBoxのItem追加

    VB.NETでの開発初心者です。 ComboBoxのItem追加について、1行づつ追加していくのは理解できているのですが、HTMLでのListBox「OPTIONS設定」の様にArrayListにて一括追加する方法がわかりません。 ご存知の方、よろしくお願いします。  <1行づつ追加>  Me.ComboBox1.Items.Clear()  Me.ComboBox1.Items.Add(New ComboItems(Key値, 表示値))    ※ComboItemsクラスは、別途作成 <一括追加>  Dim comboArray As New ArrayList  comboArray.Add(New ComboItems(Key値, 表示値))  Me.ComboBox1.Items.???(comboArray) ← ここがわからない  

  • コンボボックスのインデックス値取得について

    Visual Stdio 2008 Express Editionを使ってVBの勉強をしています。 コンボボックスのことについてお伺いしたいことがあり、 投稿させていただきました。 Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load With ComboBox1 .Items.Add("りんご") .Items.Add("みかん") .Items.Add("なし") End With End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click MsgBox("コンボボックスで選択した項目のインデックス") End Sub End Class コンボボックスで「みかん」を選択し、 ボタンを押下したときに、「みかん」のインデックス値として 「1」を出力させたいのですが、この表示方法がわからない状態です。 VB6.0であれば、ItemDataプロパティを使えばうまくいくと 思うのですが、VisualStudioだとどのプロパティを用意すれば よろしいのでしょうか。 ご教授の程お願い致します。

専門家に質問してみよう