BuddyRoach
BuddyRoach

Reputation: 162

Creating New Form Controls in Visual Basic

I am trying to have a button, when clicked, creates a new picturebox control. So that everytime I click it, it adds another new picturebox control. These pictureboxes will all have the same functions like being able to move them around and draw on them. But the button only makes one and no more after that with the following code. What am I missing?

 Public Class Form1
        Dim xpos As New Integer
        Dim ypos As New Integer
        Dim pos As New Point
        Dim x As Integer
        Dim y As Integer
        Dim canvas As New PictureBox
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

            Dim i As Integer = 0
            i = i + 1
            canvas.Name = "canvas" & i
            canvas.BackColor = Color.White
            canvas.BorderStyle = BorderStyle.FixedSingle
            canvas.Image = Nothing
            canvas.Height = TextBox1.Text
            canvas.Width = TextBox2.Text
            AddHandler canvas.MouseDown, AddressOf PictureBox1_MouseDown
            AddHandler canvas.MouseMove, AddressOf PictureBox1_MouseMove
            Controls.Add(canvas)

        End Sub
        Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
            xpos = Cursor.Position.X - canvas.Location.X
            ypos = Cursor.Position.Y - canvas.Location.Y
        End Sub

        Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
            If e.Button = Windows.Forms.MouseButtons.Left Then
                pos = MousePosition
                pos.X = pos.X - xpos
                pos.Y = pos.Y - ypos
                canvas.Location = pos
            End If
        End Sub

        Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)

        End Sub

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        End Sub
    End Class

Upvotes: 1

Views: 465

Answers (2)

Hans Passant
Hans Passant

Reputation: 941465

   Dim canvas As New PictureBox

You have multiple bugs in your code but this is the most serious one. The As New syntax ensures that you'll always create a PictureBox object, but it will only ever be one object. And of course, one variable cannot keep track of multiple picture boxes.

What you need to do is create a new one ever time the button is clicked. It is generally a good idea to keep track of the picture boxes you create. So correct code looks like:

   Dim canvases As New List(Of PictureBox)

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       Dim canvas = New PictureBox
       canvases.Add(canvas)
       canvas.Name = "canvas" & canvases.Count.ToString()
       '' etc...
   End Sub

    Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        Dim canvas = DirectCast(sender, PictureBox)
        xpos = Cursor.Position.X - canvas.Location.X
        ypos = Cursor.Position.Y - canvas.Location.Y
    End Sub

Note how the sender argument gives you a reference back to the picture box object that's being moused. Do the same thing in any other event handlers.

Upvotes: 1

Saragis
Saragis

Reputation: 1792

Increasing the counter whenever a new canvas is created:

 Public Class Form1
    Dim counter As New Integer
    ...

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        counter += 1
        canvas.Name = "canvas" & counter.ToString()
        ...

Accessing the canvas that the mouse is currently moving over:

    Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        If e.Button = Windows.Forms.MouseButtons.Left Then
            pos = MousePosition
            pos.X = pos.X - xpos
            pos.Y = pos.Y - ypos
            DirectCast(sender, PictureBox).Location = pos
        End If
    End Sub

Upvotes: 0

Related Questions