I have a program that adds controls on the fly to an auto-scroll panel. When the panel is scrolled (viewing the bottom of the panel for example) and a control is added, it looks like it is added assuming the top left corner of the panel is still at 0,0 when in fact it may be 0,500. To see what I am talking about, create an empty "Windows Forms Application" project and insert the below code into it.

Friend WithEvents Panel1 As System.Windows.Forms.Panel
    Friend WithEvents btnAdd As System.Windows.Forms.Button
    Dim ButtonCount As Integer

    Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
        Dim OnTheFlyButton = New Button
        OnTheFlyButton.Location = New Point(10, 100)
        OnTheFlyButton.Name = "Button" & ButtonCount.ToString
        OnTheFlyButton.Text = "Button " & ButtonCount.ToString
        Panel1.Controls.Add(OnTheFlyButton)
        OnTheFlyButton.BringToFront()
        ButtonCount += 1
    End Sub

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Me.Panel1 = New System.Windows.Forms.Panel
        Me.btnAdd = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'Panel1
        '
        Me.Panel1.AutoScroll = True
        Me.Panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.Panel1.Location = New System.Drawing.Point(0, 57)
        Me.Panel1.Name = "Panel1"
        Me.Panel1.Size = New System.Drawing.Size(200, 100)
        Me.Panel1.TabIndex = 0
        '
        'btnAdd
        '
        Me.btnAdd.Location = New System.Drawing.Point(4, 28)
        Me.btnAdd.Name = "btnAdd"
        Me.btnAdd.Size = New System.Drawing.Size(75, 23)
        Me.btnAdd.TabIndex = 5
        Me.btnAdd.Text = "Add"
        Me.btnAdd.UseVisualStyleBackColor = True
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(300, 200)
        Me.Controls.Add(Me.btnAdd)
        Me.Controls.Add(Me.Panel1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)
    End Sub

Now run the app and click the Add button. Scroll the panel down and you will see where it added Button 0. Click the Add button again. You will have to scroll down again to see Button 1. Add several buttons by scrolling down and then clicking the Add button. Now scroll up a little ways (not clear to the top) and click the Add button again. Scroll down a little and you will see where it created the new button over top of the old ones.

Since the location of the new button is forced to be at 10, 100 , it can't be a program bug calculating the new location incorrectly. So, what is causing it to do this and what is the proper way of adding these buttons. Do I have to try to determine how much the screen has been scrolled (i.e. find the actual panel coordinates of the upper left corner) in order to add them in the proper location?

Modified code,(red color s newly added and green s modified)

Dim ButtonCount As Integer
Dim XLoc As Integer
OnTheFlyButton.Location = New Point(XLoc, 100)
XLoc += 100

You've missed my point. The code that I posted should stack them on top of each other but it does not if the panel has been scrolled down. I need this code to stack them on top of each other regardless of where the panel is scrolled to. When the first button is placed at 10,100 and then you scroll the panel 25 points, the second button is actually placed at (10,125) instead of (10,100). Scroll again another 25 points and add a button at (10,100) and it is actually added at (10,150). Based on what the sample program is doing, to stack a second button directly on top of the first, I would have to place it at (10, 75) or (10, DesiredPosition - ScrollPosition).

The logic in my real program is adding a control at (10,100) and then later attempts to add another control at (10,130). However, because the panel has been scrolled down, it actually adds it at (10,200).

After a whole lot of research, I finally found the answer. Replace the btnAdd_Click subroutine with the following.

Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
        Dim OnTheFlyButton = New Button
        OnTheFlyButton.Location = New Point(10, 100 [B][I][U]+ Panel1.AutoScrollPosition.Y[/U][/I][/B])
        OnTheFlyButton.Name = "Button" & ButtonCount.ToString
        OnTheFlyButton.Text = "Button " & ButtonCount.ToString
        Panel1.Controls.Add(OnTheFlyButton)
        OnTheFlyButton.BringToFront()
        ButtonCount += 1
    End Sub

By including Panel1.AutoScrollPosition.Y in the Y location calculation, it adjusts the location of the new button based on where Panel1 is currently scrolled.

One more follow-up to this because I just spent a bunch of time fighting with this problem again. The controls that are being added must be visible = true at the time they are added. After they are added, they can be changed to visible = false if you don't want them shown yet. If they are visible = false when they are added, when they are set to visible = true for the first time, they are displayed in the wrong location.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.