【VB2005】動的にコントロールを作成し、処理を行う方法

このQ&Aのポイント
  • VB5.0からVB2005にアップグレードした初心者が、コントロール配列を使えなくなったことで困っています。
  • 特定の操作を行うと画面に動的にコントロールが追加され、そのコントロールのプロパティを他のコントロールから操作したい。
  • コントロールを追加することはできるが、プロパティを変更するためにコントロールにアクセスするとエラーが発生してしまう。
回答を見る
  • ベストアンサー

【VB2005】 実行時に動的にコントロールを作成した後のコントロールへの処理

こんばんわ、VB5.0を1週間ほどかじって現在2005に乗り換えたばかりのド初心者です。 (用語の使い方などが間違っている可能性があるかもしれません。おかしなところは指摘していただけるとありがたいです) VB5.0を使っていたときはコントロール配列を使って簡単にできた事が2005になってコントロール配列を使えなくなったため行き詰ってしまいました。 内容は、ある操作をすると画面にコントロールが1つずつ追加されていき、そのコントロールのプロパティを他のコントロールから操作できるようにする物です。 検索などで情報を集めて、なんとかコントロールを追加していくことができるようにはなったのですが、プロパティを変更するためにコントロールにアクセスする際にエラーになってしまって困っています。 一つだけコントロールが追加された場合は、問題なくプロパティをいじれるのですが、2つ以上追加した場合に最新のコントロール以外のプロパティをいじろうとするとエラーになってしまうのです。 下に私の作りたいプログラムを簡潔にしたサンプルソースを記述させていただきます。 間違いの指摘やアドバイスをいただければ幸いです。 FormにはAddButtonというボタンが一つだけあります。 Dim Index As Integer Private Buttons() As System.Windows.Forms.Button Private Labels() As System.Windows.Forms.Label Private Sub AddButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddButton.Click Index += 1 Me.Buttons = New System.Windows.Forms.Button(Index) {} Me.Labels = New System.Windows.Forms.Label(Index) {} Me.SuspendLayout() Me.Buttons(Index - 1) = New System.Windows.Forms.Button Me.Buttons(Index - 1).Text = Index - 1 Me.Buttons(Index - 1).Size = New Size(30, 30) Me.Buttons(Index - 1).Location = New Point((Index - 1) * 30, 50) Me.Labels(Index - 1) = New System.Windows.Forms.Label Me.Labels(Index - 1).Text = Index - 1 Me.Labels(Index - 1).Size = New Size(30, 30) Me.Labels(Index - 1).Location = New Point((Index - 1) * 30, 100) AddHandler Me.Buttons(Index - 1).Click, _ AddressOf Me.Buttons_Click Me.Controls.AddRange(Me.Buttons) Me.Controls.AddRange(Me.Labels) Me.ResumeLayout(False) End Sub Private Sub Buttons_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Labels(sender.text).ForeColor = Color.Red End Sub

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

  • ベストアンサー
  • perse
  • ベストアンサー率74% (113/152)
回答No.1

原因は >Me.Buttons = New System.Windows.Forms.Button(Index) {} です。クリックするたびこの部分で配列が全て初期化されています。 配列の中身を保持したまま配列の大きさを変える場合は ReDim Preserve Me.Buttons(Index-1) とします。 配列を使わずにlistを使用する方法もあります。 Private Index As Integer Private lstButtons As New List(Of System.Windows.Forms.Button)() Private Sub AddButton_Click(ByVal sender As System.Object...省略) Me.lstButtons.Add(New System.Windows.Forms.Button()) Me.lstButtons.Item(Index).Text = Convert.ToString(Index) Me.lstButtons.Item(Index).Size = New Size(30, 30) Index += 1 End Sub

ponknight
質問者

お礼

アドバイスありがとうございます! 教えていただいた2通りの方法を試して、両方とも上手く動かせることができました。 今回は、前者の方が現在の作りかけを修正するには楽そうなのでこちらの方法を利用させていただきます。 とても勉強になりました。 お忙しい中、本当にありがとうございました。

関連するQ&A

  • VB.NET 動的コントロールのインデックス

    VB.NET 2005で動的コントロールを複数作成し、 クリックされた動的コントロールのインデックスを 調べる方法はないでしょうか? 以下の様に動的コントロールLabel01とLabel02が複数並んでいて Label01(3)をクリックした時に、Label02(3)も同時に処理 したいのでインデックスを調べたいのですが方法がわかりません。 [Label01(1)] [Label02(1)] [Label01(2)] [Label02(2)] [Label01(3)] [Label02(3)] [Label01(4)] [Label02(4)] [Label01(5)] [Label02(5)]    :      : [Label01(x)] [Label02(x)] '----------------------------------------------- 'Label01(3)がクリックされたら、Label02(3)も"ok"を表示する Private Sub Lab01_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Dim lab01 As Label = CType(sender, Label) System.Diagnostics.Debug.WriteLine(lab01.Text & "が押されました。") lab01.Text = "ok" lab02(?).Text = "ok"  '←インデックスがわかりません End Sub '-----------------------------------------------

  • VB.NETで同一処理を実行させたい

    VB.NETでプログラム組んでいます。 下のように、あるフォームの中でメニューを設定して、メニューを選択すると処理を実行するようにしています。 Private Sub OpenMenu_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenMenu.Click (オープンメニュークリック時の処理) End Sub このとき、同一フォームの中にツールバーを下のように設定して 上の(オープンメニュークリック時の処理)を実行させるには、 次の???の記述はどのようにすればよいのでしょう?。 (オープンメニュークリック時の処理)はかなり長い処理(関数(Private Sub Function)も含む)になってしまっているので、コピーして記述するのも嫌なのです。 普通に 「OpenMenu_Click()」 でよいのかと思っていましたが、引数(eでしょうか?)を設定しないとだめのようで、。 どのようにすればよいのかわかりません。すみませんが、ご教示ください。 Private Sub ToolBar1_ButtonClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolBarButtonClickEventArgs) Handles ToolBar1.ButtonClick   ??? End Sub

  • 描画した後での塗りるぶし VB

    丸を描画後にColorDialogで指定された色で丸の範囲だけ塗りつぶすというプログラムを作っているのですが、なかなかうまくいきません。 丸は、このように描画するようにしています。 Private Sub PictureBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove If (e.Button = MouseButtons.Left) Then Dim g As Graphics = PictureBox1.CreateGraphics() Dim ePos As MouseEventArgs PictureBox1.Refresh() g.DrawEllipse(New Pen(Color.Black, 2), Spos.X, Spos.Y, e.X - Spos.X, e.Y - Spos.Y) ePos = e g.Dispose() End If End Sub Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown If (e.Button = System.Windows.Forms.MouseButtons.Left) Then Spos = e End If End Sub VB2010を使っています。 どなたか教えていただけるとありがたいです。よろしくお願いします。

  • Elseifのコードが分かりません。(至急)

    急ぎのため再度の質問失礼します。 3つの数字すべてが7のとき、メッセージ1を出し、 どれか2つだけが7のときは、メッセージ2を出し、 どれか1つだけが7のときは、メッセージ3を出し、 どこにも7が含まれていないときは、メッセージ4を出すようにEndifを使って書きたいのですが、正しいコードを教えて下さい。 Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Randomize() End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Me.Close() End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click PictureBox1.Visible = False Label4.Visible = False Label1.Text = CStr(Int(Rnd() * 10)) Label2.Text = CStr(Int(Rnd() * 10)) Label3.Text = CStr(Int(Rnd() * 10)) If End If End Sub Private Sub Label1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label1.Click End Sub Private Sub Label3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label3.Click End Sub Private Sub Label5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label5.Click End Sub End Class よろしくお願いします。

  • 【VB2005】コントロールを配列に。

    下記のコードを変更して、コントロールの値を配列に代入して、 その値をもとに、ボタンを複製して追加したいと思っています。 Public Class frmStart Dim btnNewButton1 As New Button Private Sub frmStart_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load NewButton1.Text = "処理1" btnNewButton1.ForeColor = Color.DimGray btnNewButton1.Location = New Point(10, 100) btnNewButton1.Size = New Size(180, 30) '// ボタンを追加します Me.Controls.Add(btnNewButton1) end sub End Class やりたいことは、Dim btnNewButton() As New Button のようにデータを配列にして、 btnNewButton(0).ForeColor = Color.DimGray btnNewButton(0).Location = New Point(10, 100) btnNewButton(0).Size = New Size(180, 30) btnNewButton(1).ForeColor = Color.DimGray btnNewButton(1).Location = New Point(380, 100) btnNewButton(1).Size = New Size(180, 30) '// ボタンを追加します Me.Controls.Add(btnNewButton(0))     Me.Controls.Add(btnNewButton(1)) という事をしたいのですが、方法が解らなくて困ってます。 お知恵を貸してください。

  • VB2010平面移動

    VisualBasic2010においてMouseDown、DragDropを用いてPanelを移動させるコードを書きました。 Panel4へPanel1,Panel2,Panel3を移動させるというものです。  例) Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Shown Panel4.AllowDrop = True End Sub Private Sub Panel1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown Panel1.DoDragDrop(Panel1, DragDropEffects.Move) End Sub Private Sub Panel2_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel2.MouseDown Panel2.DoDragDrop(Panel2, DragDropEffects.Move) End Sub Private Sub Panel3_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel3.MouseDown Panel3.DoDragDrop(Panel3, DragDropEffects.Move) End Sub Private Sub Panel4_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel4.DragDrop Dim srsPnl As Panel = e.Data.GetData(GetType(Panel)) Dim dstPnl As New Panel dstPnl.Size = srsPnl.Size dstPnl.Location = Panel4.PointToClient(CursorPosition) 'New Point(e.X, e.Y) dstPnl.BackColor = srsPnl.BackColor AddHandler dstPnl.MouseDown, AddressOf dstPnl_MouseDown AddHandler dstPnl.MouseMove, AddressOf dstPnl_MouseMove Panel4.Controls.Add(dstPnl) End Sub Private Sub Panel4_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel4.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 このようにした場合、初めに移動させたものが最前にきてしまいます。(画像参照) 私はPanel1(黒)を最前に持っていきたいと考えています。 もしお時間等ありましたら、お力添えをいただけると嬉しく思います。 どうかよろしくお願いします。

  • VBでタイピングゲーム作成

    Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged If TextBox1.Text = Label1.Text Then Label1.Text = "haradamunetoki" Label2.Text = "原田宗時" TextBox1.Text = "" Else Label3.Text = "違います" Private TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged End If If TextBox1.Text = Label1.Text Then Label1.Text = "katakurakojuro" Label2.Text = "片倉小十郎" TextBox1.Text = "" Else Label3.Text = "違います" End If ――最初ラベル1にはdatemasamune、ラベル2には伊達政宗と表示してあって、主に判断の基準となるのはラベル1ですが、 最初のEnd If文までの間で繰り返しのような感じになってしまっていて 次の片倉小十郎に行くことができません。 先生に話しを聞いたところ、文法をよく理解していないとのこと…。 次のif文にいくにはどうしたらいいのでしょうか?

  • VB2010でのコントロール多次元配列について

    教えてください。 実行中にコントロールを生成したいのですが、 Public Class Form1  Private myTxt(,) As System.Windows.Forms.TextBox  Me.myTxt = New System.Windows.Forms.TextBox(59, 2) {}  Dim i As Integer  Dim j As Integer  Dim h As Integer  Dim p As Integer  h = 10  p = 100  For i = 0 To Me.myTxt.GetLength(0) - 1   For j = 0 To Me.myTxt.GetLength(1) - 1    Me.myTxt(i, j) = New System.Windows.Forms.TextBox    Me.myTxt(i, j).Name = "myTxt" + i.ToString() + j.ToString()    Me.myTxt(i, j).Size = New Size(100, 30)    Me.myTxt(i, j).Location = New Point(p, h)    p = p + 100   Next j   h = h + 30  Next i  Me.myPnl.Controls.AddRange(Me.myTxt) と書くと最後の行が波線になり、 “型 'System.Windows.Forms.TextBox の 2 次元配列' の値を 'System.Windows.Forms.Control' に変換できません。”とエラーになります。 これはAddRangeは多次元配列に使用できないということなのでしょうか? 色々検索してみましたが、コントロールの生成に関する多次元配列が見つけられずに 困っていました。 最後のAddRange(Me.myTxt)をAdd(Me.myTxt(i,j))などと変えたりしても別のエラーになり、 基本的に間違っている気がしますがどこだかがわかりません。 詳しい方、宜しくお願い致します。

  • VB2010 bitmapとして取り込む

    現在、panelを移動させて図形を作成するプログラムを書いています。 このpanelを移動させて作成した図形を画像?(bitmap等)として取り込み、他のフォームで読み込ませたいと考えております。 panelを移動させるコード Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Shown Panel4.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 sender.DoDragDrop(sender, DragDropEffects.Move) End Sub Private Sub Panel4_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel4.DragDrop Dim srsPnl As Panel = e.Data.GetData(GetType(Panel)) Dim dstPnl As New Panel dstPnl.Size = srsPnl.Size dstPnl.Location = Panel4.PointToClient(CursorPosition) 'New Point(e.X, e.Y) dstPnl.BackColor = srsPnl.BackColor AddHandler dstPnl.MouseDown, AddressOf dstPnl_MouseDown AddHandler dstPnl.MouseMove, AddressOf dstPnl_MouseMove Panel4.Controls.Add(dstPnl) End Sub Private Sub Panel4_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel4.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 上記のコードでpanel4へpanel1,panel2,panel3を自由に移動させて任意の図形を作成することができます。 このコードを用いて画像のような図形を作った際に、その図形を他のフォームで読み込ませたいです。 わかる方がいらっしゃいましたら、お力添えしていただけると幸いです。 よろしくお願いします。

  • 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 これが現在書いているコードです。

専門家に質問してみよう