none
How Can I Scroll a Panel So That A Particular Control Is At THE TOP of the Panel? RRS feed

  • Question

  • ScrollControlIntoView puts the control at the bottom.  (Context below.)

    I think that ScrollToControl provides the point that the panel has to scroll to but I've had no luck with any of these attempts:

    'pnlFromItems.SetDisplayRectLocation(ptTargetLoc.X, ptTargetLoc.Y)
                    'pnlFromItems.AutoScrollPosition = ptTargetLoc
                    pnlFromItems.AutoScrollOffset = ptTargetLoc

    Context:  Each control in the panel represents a US state - the controls are in a list format.  If the user enters a single character I want the panel to scroll so that the state's control is at the top of the panel.  If the user enters, for example, a N he may want any one of several states.  It would be much more helpful if the panel positioned itself so that the first state beginning with a N was at the top of the panel.  

    I'll appreciate any assistance anyone can give me.  Thanks,  Bob

    Monday, May 28, 2018 5:15 PM

All replies

  • I found that I need to set the AutoScrollPosition to New Point(0, 0) before autoscrolling to a control which should not be the case really. As Control.AutoScrollOffset Property says "Gets or sets where this control is scrolled to in ScrollControlIntoView.". Or maybe I'm not using it correctly. Anyhow I put about 9 buttons in various order on the Panel so that most were outside of the scroll area and scrolled to Button7 constantly.

    But your requirement is for alot more that I can not perform nor do I have your project to attempt it with or want to do it. But this code scrolls to Button7 everytime. Although it is not centered in the scrolled area and not at the top as you desire. There would need to be some offsets used by you to figure out how to perform that so every control could be at the top in the center which would be difficult to perform IMO.

    Option Strict On
    
    Public Class Form1
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.Location = New Point(CInt((Screen.PrimaryScreen.WorkingArea.Width / 2) - (Me.Width / 2)), CInt((Screen.PrimaryScreen.WorkingArea.Height / 2) - (Me.Height / 2)))
            Panel1.AutoScroll = True
        End Sub
    
        Private Sub Button10_Click(sender As Object, e As EventArgs) Handles Button10.Click
            Panel1.AutoScrollPosition = New Point(0, 0)
            Panel1.AutoScrollPosition = Button7.Location
        End Sub
    End Class


    La vida loca

    Tuesday, May 29, 2018 3:06 AM
  • Thank you Mr. Monkeyboy for your response.  Since seeing your response I have tried many variations of code involving AutoScrollPosition and ScrollControlIntoView.  But have had no luck.  In fact yesterday I had code which at least did scroll the control into view but at the bottom of the view instead of the top of the view.  Today I am unable to get the control to scroll into view at all.  Here's the last code I have tried: 

    For Each adc As AddDeleteControl In pnlFromItems.Controls
                If dakey.ToString.ToLower = adc.tbxName.Text.Substring(0, 1).ToLower Then
                    'Dim asp = pnlFromItems.AutoScrollPosition
                    MsgBox(adc.tbxName.Text)
                    Dim ptTargetLoc As Point = adc.Location
                    'pnlFromItems.SetDisplayRectLocation(ptTargetLoc.X, ptTargetLoc.Y)
                    'pnlFromItems.AutoScrollPosition = ptTargetLoc
                    'pnlFromItems.AutoScrollOffset = ptTargetLoc
                    With pnlFromItems
                        AutoScrollPosition = New Point(0, 0)
                        AutoScrollPosition = ptTargetLoc
                        ScrollControlIntoView(adc)
                    End With
                    Exit For
                End If
            Next

    Although this code certainly does not work (for me at least) it does do something which may suggest a solution although I am not able to see what that solution would be.  When the control for Alabama is at the top of the panel and  I enter "p" nothing happens.  However, if the control for Wyoming is at the bottom of the panel and I enter "p" the list of states is scrolled so that the control for Alabama ends up at the top.  So at least some motion occurs.  

    If you or anyone else has any further advice I would appreciate it.  This is driving me nuts.  Thanks,  Bob

    Tuesday, May 29, 2018 1:49 PM
  • ScrollControlIntoView scrolls the control into the bottom right area of the panels scrollable display area.

    The panel I am using has 10 buttons in it. 1 through 9 are basically centered in the Panel with the panel originally rather large in size so none of the buttons show when I shrink the panel on the Form. However when the buttons are placed on the panel at large size I also had to add a control to the bottom right corner of the Panel to get this to work correctly. And I suppose that control could have its visibility set to false. Anyhow in the designer I then shrink the panel so that no controls are exposed.

    Therefore Buttons 1 through 9 are in the very center of the panel with the last control, Button11 in this instance, set in the bottom right corner of the panel. Now when I use this code the Button autoscrolled to will be at the top middle of the panels scroll area although other buttons can be seen around it.

    Therefore you should size the panel initially so all controls displayed in it will be in an area that can be scrolled into view such that a control can be displayed at the top center of the panels displayed client rectangle.

        Private Sub Button10_Click(sender As Object, e As EventArgs) Handles Button10.Click
            ' Button1 to 9
            Panel1.AutoScrollPosition = New Point(0, 0)
            Panel1.AutoScrollPosition = New Point(Button2.Location.X - CInt(Panel1.ClientRectangle.Width / 2) + CInt(Button2.Width / 2), Button2.Location.Y)
        End Sub


    La vida loca


    Friday, June 1, 2018 12:20 AM
  • Thank you Mr. Monkeyboy for your continued help.  Unfortunately I have to table this work for awhile.  I'll experiment with your solution when I can return to it.  Thanks again,  Bob
    Monday, June 4, 2018 1:35 PM
  • Hi Bob,

    Looking forward to your update, and if Mr. Monkeyboy's reply provided you with a solution please mark the reply as answered as this will help others looking for the same or similar issues down the road.

    Regards,

    Frankie


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, June 6, 2018 1:24 AM
    Moderator
  • Here is a conceptual open ended idea to try with modifications to fit your needs.

    ''' <summary>
    ''' This is a conceptual example.
    ''' There are several buttons on Panel1, in form load
    ''' they are loaded into a List(Of Item). when the SelectedIndex
    ''' changes on the ListBox that control is scrolled into view.
    ''' 
    ''' Each instance of the Item class does not have to be a Button.
    ''' The Button property could be of type Control to handle all
    ''' controls in the Panel.
    ''' 
    ''' For the keystroke part you can query the control names in
    ''' the underlying List(Of Control), use Lamda to find it and
    ''' then use ScrollControlIntoView(foundControl)
    ''' </summary>
    Public Class Form2
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Panel1.AutoScroll = True
    
            Dim buttonList = Panel1.Controls.OfType(Of Button).
                Select(Function(c) New Item With {.Text = c.Text, .Button = c}).
                ToList
    
            ListBox1.DisplayMember = "Text"
            ListBox1.DataSource = buttonList
        End Sub
        Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) _
            Handles ListBox1.SelectedIndexChanged
    
            Dim bItem = CType(ListBox1.SelectedItem, Item)
            Panel1.ScrollControlIntoView(bItem.Button)
    
        End Sub
    End Class
    Public Class Item
        Public Property Text As String
        Public Property Button As Button
    End Class


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Wednesday, June 6, 2018 1:59 PM
    Moderator